4 * Definitions for the Windows Overlay Filesystem filter (WOF) ioctls, as well
5 * some definitions for associated undocumented data structures.
7 * Copyright 2022 Eric Biggers
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
34 #include "wimlib/compiler.h"
35 #include "wimlib/types.h"
38 * The Windows Overlay Filesystem filter (WOF, a.k.a. wof.sys) is a filesystem
39 * filter driver, available in Windows 8.1 and later, which allows files to be
40 * "externally backed", meaning that their data is stored in another location,
41 * possibly in compressed form.
43 * WOF implements a plug-in mechanism by which a specific "provider" is
44 * responsible for actually externally backing a given file. The currently
45 * known providers are:
47 * - The WIM provider: allows a file to be externally backed by a
48 * compressed resource in a WIM archive
49 * - The file provider: allows a file to be "externally backed" by a named
50 * data stream stored with the file itself, where that named data stream
51 * has the format of a compressed WIM resource
53 * For both of these providers, externally backed files are effectively
54 * read-only. If you try to write to such a file, Windows automatically
55 * decompresses it and turns it into a regular, non-externally-backed file.
57 * WOF provides various ioctls that control its operation. For example,
58 * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
60 * WOF external backings are implemented using reparse points. One consequence
61 * of this is that WOF external backings can only be set on files that do not
62 * already have a reparse point set. Another consequence of this is that it is
63 * possible to create a WOF external backing by manually creating the reparse
64 * point, although this requires dealing with undocumented data structures and
65 * it only works when the WOF driver is not currently attached to the volume.
67 * Note that only the unnamed data stream portion of a file can be externally
68 * backed. Other NTFS streams and metadata are not externally backed.
72 /*----------------------------------------------------------------------------*
73 * WOF ioctl definitions *
74 *----------------------------------------------------------------------------*/
76 #ifndef WOF_CURRENT_VERSION
77 /* Identifies a file backing provider and the overlay service version it supports.
78 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_wof_external_info */
79 typedef struct _WOF_EXTERNAL_INFO {
80 #define WOF_CURRENT_VERSION 1
83 } WOF_EXTERNAL_INFO, *PWOF_EXTERNAL_INFO;
84 #endif /* WOF_CURRENT_VERSION */
86 /* WIM provider ("WIMBoot") */
87 #ifndef WOF_PROVIDER_WIM
88 #define WOF_PROVIDER_WIM 1
90 * The identifier and status information for the Windows Image File (WIM)
91 * external backing provider.
92 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_wim_provider_external_info
94 typedef struct _WIM_PROVIDER_EXTERNAL_INFO {
95 #define WIM_PROVIDER_CURRENT_VERSION 1
98 LARGE_INTEGER DataSourceId;
99 #define WIM_PROVIDER_HASH_SIZE 20
100 UCHAR ResourceHash[WIM_PROVIDER_HASH_SIZE];
101 } WIM_PROVIDER_EXTERNAL_INFO, *PWIM_PROVIDER_EXTERNAL_INFO;
102 #endif /* WOF_PROVIDER_WIM */
104 /* File provider ("system compression") */
105 #ifndef WOF_PROVIDER_FILE
106 #define WOF_PROVIDER_FILE 2
107 /* Defines metadata specific to files provided by WOF_PROVIDER_FILE.
108 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_provider_external_info_v1 */
109 typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
110 #define FILE_PROVIDER_CURRENT_VERSION 1
112 #define FILE_PROVIDER_COMPRESSION_XPRESS4K 0
113 #define FILE_PROVIDER_COMPRESSION_LZX 1
114 #define FILE_PROVIDER_COMPRESSION_XPRESS8K 2
115 #define FILE_PROVIDER_COMPRESSION_XPRESS16K 3
118 } FILE_PROVIDER_EXTERNAL_INFO_V1, *PFILE_PROVIDER_EXTERNAL_INFO_V1;
119 #endif /* WOF_PROVIDER_FILE */
121 /* Sets the backing source for a file.
122 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-set-external-backing */
123 #ifndef FSCTL_SET_EXTERNAL_BACKING
124 #define FSCTL_SET_EXTERNAL_BACKING \
125 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 195, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
128 /* Gets the backing information for a file from an external backing provider.
129 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-get-external-backing */
130 #ifndef FSCTL_GET_EXTERNAL_BACKING
131 #define FSCTL_GET_EXTERNAL_BACKING \
132 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 196, METHOD_BUFFERED, FILE_ANY_ACCESS)
135 #ifndef STATUS_OBJECT_NOT_EXTERNALLY_BACKED
136 #define STATUS_OBJECT_NOT_EXTERNALLY_BACKED 0xC000046D
139 /* Removes the association of a file with an external backing provider.
140 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-delete-external-backing */
141 #ifndef FSCTL_DELETE_EXTERNAL_BACKING
142 #define FSCTL_DELETE_EXTERNAL_BACKING \
143 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 197, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
146 /* Begins or continues an enumeration of files on a volume that have a backing source.
147 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-enum-external-backing */
148 #ifndef FSCTL_ENUM_EXTERNAL_BACKING
149 #define FSCTL_ENUM_EXTERNAL_BACKING \
150 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 198, METHOD_BUFFERED, FILE_ANY_ACCESS)
153 /* Enumerates all the data sources from a backing provider for a specified volume.
154 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-enum-overlay */
155 #ifndef FSCTL_ENUM_OVERLAY
156 #define FSCTL_ENUM_OVERLAY \
157 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 199, METHOD_NEITHER, FILE_ANY_ACCESS)
158 typedef struct _WIM_PROVIDER_OVERLAY_ENTRY {
159 ULONG NextEntryOffset;
160 LARGE_INTEGER DataSourceId;
162 ULONG WimFileNameOffset;
166 } WIM_PROVIDER_OVERLAY_ENTRY, *PWIM_PROVIDER_OVERLAY_ENTRY;
167 #endif /* FSCTL_ENUM_OVERLAY */
169 /* Add a new external backing source to a volume's namespace.
170 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-add-overlay */
171 #ifndef FSCTL_ADD_OVERLAY
172 #define FSCTL_ADD_OVERLAY \
173 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 204, METHOD_BUFFERED, FILE_WRITE_DATA)
174 typedef struct _WIM_PROVIDER_ADD_OVERLAY_INPUT {
175 #define WIM_BOOT_NOT_OS_WIM 0
176 #define WIM_BOOT_OS_WIM 1
179 ULONG WimFileNameOffset;
180 ULONG WimFileNameLength;
181 } WIM_PROVIDER_ADD_OVERLAY_INPUT, *PWIM_PROVIDER_ADD_OVERLAY_INPUT;
182 #endif /* FSCTL_ADD_OVERLAY */
184 /* Removes a backing source from a volume.
185 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-remove-overlay */
186 #ifndef FSCTL_REMOVE_OVERLAY
187 #define FSCTL_REMOVE_OVERLAY \
188 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 205, METHOD_BUFFERED, FILE_WRITE_DATA)
189 typedef struct _WIM_PROVIDER_REMOVE_OVERLAY_INPUT {
190 LARGE_INTEGER DataSourceId;
191 } WIM_PROVIDER_REMOVE_OVERLAY_INPUT, *PWIM_PROVIDER_REMOVE_OVERLAY_INPUT;
192 #endif /* FSCTL_REMOVE_OVERLAY */
194 /* Updates a new data source identifier for a backing source attached to a volume.
195 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-update-overlay */
196 #ifndef FSCTL_UPDATE_OVERLAY
197 #define FSCTL_UPDATE_OVERLAY \
198 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 206, METHOD_BUFFERED, FILE_WRITE_DATA)
199 typedef struct _WIM_PROVIDER_UPDATE_OVERLAY_INPUT {
200 LARGE_INTEGER DataSourceId;
201 ULONG WimFileNameOffset;
202 ULONG WimFileNameLength;
203 } WIM_PROVIDER_UPDATE_OVERLAY_INPUT, *PWIM_PROVIDER_UPDATE_OVERLAY_INPUT;
204 #endif /* FSCTL_UPDATE_OVERLAY */
206 /*----------------------------------------------------------------------------*
207 * WOF reparse point and WimOverlay.dat structs (undocumented) *
208 *----------------------------------------------------------------------------*/
211 * Format of the WIM provider reparse data. This is the data which follows the
212 * portion of the reparse point common to WOF. (The common portion consists of
213 * a reparse point header where the reparse tag is 0x80000017, then a
214 * WOF_EXTERNAL_INFO struct which specifies the provider.)
216 * Note that Microsoft does not document any of the reparse point formats for
217 * WOF, although they document the structures which must be passed into the
218 * ioctls, which are often similar.
220 struct wim_provider_rpdata {
221 /* Set to 2. Uncertain meaning. */
224 /* 0 when WIM provider active, otherwise
225 * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
226 * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
229 /* Integer ID that identifies the WIM. */
232 /* SHA-1 message digest of the file's unnamed data stream. */
233 u8 unnamed_data_stream_hash[20];
235 /* SHA-1 message digest of the WIM's blob table as stored on disk. */
236 u8 blob_table_hash[20];
238 /* Uncompressed size of the file's unnamed data stream, in bytes. */
239 le64 unnamed_data_stream_size;
241 /* Size of the file's unnamed data stream as stored in the WIM file.
242 * If this is the same as unnamed_data_stream_size, then the stream is
243 * uncompressed. If this is the *not* the same as
244 * unnamed_data_stream_size, then the stream is compressed. */
245 le64 unnamed_data_stream_size_in_wim;
247 /* Byte offset of the file's unnamed data stream in the WIM. */
248 le64 unnamed_data_stream_offset_in_wim;
251 /* WIM-specific information about a WIM data source */
252 struct WimOverlay_dat_entry_1 {
254 /* Identifier for the WIM data source, (normally allocated by
255 * FSCTL_ADD_OVERLAY). Every 'WimOverlay_dat_entry_1' should have a
256 * different value for this. */
259 /* Byte offset, from the beginning of the file, of the corresponding
260 * 'struct WimOverlay_dat_entry_2' for this WIM data source. */
263 /* Size, in bytes, of the corresponding 'struct WimOverlay_dat_entry_2
264 * for this WIM data source, including wim_file_name and its null
268 /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM. */
271 /* Index of the image in the WIM to use??? (This doesn't really make
272 * sense, since WIM files combine file data "blobs" for all images into
273 * a single table. Set to 1 if unsure...) */
276 /* GUID of the WIM file (copied from the WIM header, offset +0x18). */
281 * Format of file: "\System Volume Information\WimOverlay.dat"
283 * Not documented by Microsoft.
285 * The file consists of a 'struct WimOverlay_dat_header' followed by one or more
286 * 'struct WimOverlay_dat_entry_1', followed by the same number of 'struct
287 * WimOverlay_dat_entry_2'. Note that 'struct WimOverlay_dat_entry_1' is of
288 * fixed length, whereas 'struct WimOverlay_dat_entry_2' is of variable length.
290 struct WimOverlay_dat_header {
291 /* Set to WIMOVERLAY_DAT_MAGIC */
293 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
295 /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION) */
296 le32 wim_provider_version;
298 /* Set to 0x00000028 */
301 /* Set to number of WIMs registered (listed in the file) */
304 /* The next available data source ID. This is tracked so that data
305 * source IDs are never reused, even if a WIM is unregistered. */
306 le64 next_data_source_id;
308 struct WimOverlay_dat_entry_1 entry_1s[];
311 /* Location information about a WIM data source */
312 struct WimOverlay_dat_entry_2 {
319 /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
320 * wim_file_name and its null terminator. */
333 /* Size of this inner structure, in bytes. */
334 le32 inner_struct_size;
351 /*************************
352 * Partition information
353 ************************/
355 /* Partition identifier */
357 /* (For MBR-formatted disks) */
359 /* Offset, in bytes, of the MBR partition, from
360 * the beginning of the disk. */
361 le64 part_start_offset;
367 /* (For GPT-formatted disks) */
369 /* Unique GUID of the GPT partition */
370 u8 part_unique_guid[16];
377 /***********************
379 **********************/
381 /* 1 for MBR, 0 for GPT */
382 le32 partition_table_type;
383 #define WIMOVERLAY_PARTITION_TYPE_MBR 1
384 #define WIMOVERLAY_PARTITION_TYPE_GPT 0
386 /* Disk identifier */
388 /* (For MBR-formatted disks) */
390 /* 4-byte ID of the MBR disk */
397 /* (For GPT-formatted disks) */
399 /* GUID of the GPT disk */
404 /* Set to 0. (This is the right size for some sort of optional
406 le32 unknown_0x58[4];
408 /**************************
409 * Location in filesystem
410 *************************/
412 /* Null-terminated path to WIM file. Begins with \ but does
413 * *not* include drive letter! */
414 utf16lechar wim_file_name[];
418 static _unused_attribute void
419 wof_check_structs(void)
421 STATIC_ASSERT(sizeof(struct WimOverlay_dat_header) == 24);
422 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_1) == 40);
423 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_2) == 104);