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"
40 * The Windows Overlay Filesystem filter (WOF, a.k.a. wof.sys) is a filesystem
41 * filter driver, available in Windows 8.1 and later, which allows files to be
42 * "externally backed", meaning that their data is stored in another location,
43 * possibly in compressed form.
45 * WOF implements a plug-in mechanism by which a specific "provider" is
46 * responsible for actually externally backing a given file. The currently
47 * known providers are:
49 * - The WIM provider: allows a file to be externally backed by a
50 * compressed resource in a WIM archive
51 * - The file provider: allows a file to be "externally backed" by a named
52 * data stream stored with the file itself, where that named data stream
53 * has the format of a compressed WIM resource
55 * For both of these providers, externally backed files are effectively
56 * read-only. If you try to write to such a file, Windows automatically
57 * decompresses it and turns it into a regular, non-externally-backed file.
59 * WOF provides various ioctls that control its operation. For example,
60 * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
62 * WOF external backings are implemented using reparse points. One consequence
63 * of this is that WOF external backings can only be set on files that do not
64 * already have a reparse point set. Another consequence of this is that it is
65 * possible to create a WOF external backing by manually creating the reparse
66 * point, although this requires dealing with undocumented data structures and
67 * it only works when the WOF driver is not currently attached to the volume.
69 * Note that only the unnamed data stream portion of a file can be externally
70 * backed. Other NTFS streams and metadata are not externally backed.
74 /*----------------------------------------------------------------------------*
75 * WOF ioctl definitions *
76 *----------------------------------------------------------------------------*/
78 #ifndef WOF_CURRENT_VERSION
79 /* Identifies a file backing provider and the overlay service version it supports.
80 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_wof_external_info */
81 typedef struct _WOF_EXTERNAL_INFO {
82 #define WOF_CURRENT_VERSION 1
85 } WOF_EXTERNAL_INFO, *PWOF_EXTERNAL_INFO;
86 #endif /* WOF_CURRENT_VERSION */
88 /* WIM provider ("WIMBoot") */
89 #ifndef WOF_PROVIDER_WIM
90 #define WOF_PROVIDER_WIM 1
92 * The identifier and status information for the Windows Image File (WIM)
93 * external backing provider.
94 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_wim_provider_external_info
96 typedef struct _WIM_PROVIDER_EXTERNAL_INFO {
97 #define WIM_PROVIDER_CURRENT_VERSION 1
100 LARGE_INTEGER DataSourceId;
101 #define WIM_PROVIDER_HASH_SIZE 20
102 UCHAR ResourceHash[WIM_PROVIDER_HASH_SIZE];
103 } WIM_PROVIDER_EXTERNAL_INFO, *PWIM_PROVIDER_EXTERNAL_INFO;
104 #endif /* WOF_PROVIDER_WIM */
106 /* File provider ("system compression") */
107 #ifndef WOF_PROVIDER_FILE
108 #define WOF_PROVIDER_FILE 2
109 /* Defines metadata specific to files provided by WOF_PROVIDER_FILE.
110 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_provider_external_info_v1 */
111 typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
112 #define FILE_PROVIDER_CURRENT_VERSION 1
114 #define FILE_PROVIDER_COMPRESSION_XPRESS4K 0
115 #define FILE_PROVIDER_COMPRESSION_LZX 1
116 #define FILE_PROVIDER_COMPRESSION_XPRESS8K 2
117 #define FILE_PROVIDER_COMPRESSION_XPRESS16K 3
120 } FILE_PROVIDER_EXTERNAL_INFO_V1, *PFILE_PROVIDER_EXTERNAL_INFO_V1;
121 #endif /* WOF_PROVIDER_FILE */
123 /* Sets the backing source for a file.
124 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-set-external-backing */
125 #ifndef FSCTL_SET_EXTERNAL_BACKING
126 #define FSCTL_SET_EXTERNAL_BACKING \
127 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 195, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
130 /* Gets the backing information for a file from an external backing provider.
131 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-get-external-backing */
132 #ifndef FSCTL_GET_EXTERNAL_BACKING
133 #define FSCTL_GET_EXTERNAL_BACKING \
134 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 196, METHOD_BUFFERED, FILE_ANY_ACCESS)
137 #ifndef STATUS_OBJECT_NOT_EXTERNALLY_BACKED
138 #define STATUS_OBJECT_NOT_EXTERNALLY_BACKED 0xC000046D
141 /* Removes the association of a file with an external backing provider.
142 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-delete-external-backing */
143 #ifndef FSCTL_DELETE_EXTERNAL_BACKING
144 #define FSCTL_DELETE_EXTERNAL_BACKING \
145 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 197, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
148 /* Begins or continues an enumeration of files on a volume that have a backing source.
149 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-enum-external-backing */
150 #ifndef FSCTL_ENUM_EXTERNAL_BACKING
151 #define FSCTL_ENUM_EXTERNAL_BACKING \
152 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 198, METHOD_BUFFERED, FILE_ANY_ACCESS)
155 /* Enumerates all the data sources from a backing provider for a specified volume.
156 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-enum-overlay */
157 #ifndef FSCTL_ENUM_OVERLAY
158 #define FSCTL_ENUM_OVERLAY \
159 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 199, METHOD_NEITHER, FILE_ANY_ACCESS)
161 typedef struct _WIM_PROVIDER_OVERLAY_ENTRY {
162 ULONG NextEntryOffset;
163 LARGE_INTEGER DataSourceId;
165 ULONG WimFileNameOffset;
169 } WIM_PROVIDER_OVERLAY_ENTRY, *PWIM_PROVIDER_OVERLAY_ENTRY;
171 /* Add a new external backing source to a volume's namespace.
172 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-add-overlay */
173 #ifndef FSCTL_ADD_OVERLAY
174 #define FSCTL_ADD_OVERLAY \
175 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 204, METHOD_BUFFERED, FILE_WRITE_DATA)
177 typedef struct _WIM_PROVIDER_ADD_OVERLAY_INPUT {
178 #define WIM_BOOT_NOT_OS_WIM 0
179 #define WIM_BOOT_OS_WIM 1
182 ULONG WimFileNameOffset;
183 ULONG WimFileNameLength;
184 } WIM_PROVIDER_ADD_OVERLAY_INPUT, *PWIM_PROVIDER_ADD_OVERLAY_INPUT;
186 /* Removes a backing source from a volume.
187 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-remove-overlay */
188 #ifndef FSCTL_REMOVE_OVERLAY
189 #define FSCTL_REMOVE_OVERLAY \
190 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 205, METHOD_BUFFERED, FILE_WRITE_DATA)
192 typedef struct _WIM_PROVIDER_REMOVE_OVERLAY_INPUT {
193 LARGE_INTEGER DataSourceId;
194 } WIM_PROVIDER_REMOVE_OVERLAY_INPUT, *PWIM_PROVIDER_REMOVE_OVERLAY_INPUT;
196 /* Updates a new data source identifier for a backing source attached to a volume.
197 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-update-overlay */
198 #ifndef FSCTL_UPDATE_OVERLAY
199 #define FSCTL_UPDATE_OVERLAY \
200 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 206, METHOD_BUFFERED, FILE_WRITE_DATA)
202 typedef struct _WIM_PROVIDER_UPDATE_OVERLAY_INPUT {
203 LARGE_INTEGER DataSourceId;
204 ULONG WimFileNameOffset;
205 ULONG WimFileNameLength;
206 } WIM_PROVIDER_UPDATE_OVERLAY_INPUT, *PWIM_PROVIDER_UPDATE_OVERLAY_INPUT;
208 /*----------------------------------------------------------------------------*
209 * WOF reparse point and WimOverlay.dat structs (undocumented) *
210 *----------------------------------------------------------------------------*/
213 * Format of the WIM provider reparse data. This is the data which follows the
214 * portion of the reparse point common to WOF. (The common portion consists of
215 * a reparse point header where the reparse tag is 0x80000017, then a
216 * WOF_EXTERNAL_INFO struct which specifies the provider.)
218 * Note that Microsoft does not document any of the reparse point formats for
219 * WOF, although they document the structures which must be passed into the
220 * ioctls, which are often similar.
222 struct wim_provider_rpdata {
223 /* Set to 2. Uncertain meaning. */
226 /* 0 when WIM provider active, otherwise
227 * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
228 * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
231 /* Integer ID that identifies the WIM. */
234 /* SHA-1 message digest of the file's unnamed data stream. */
235 u8 unnamed_data_stream_hash[20];
237 /* SHA-1 message digest of the WIM's blob table as stored on disk. */
238 u8 blob_table_hash[20];
240 /* Uncompressed size of the file's unnamed data stream, in bytes. */
241 le64 unnamed_data_stream_size;
243 /* Size of the file's unnamed data stream as stored in the WIM file.
244 * If this is the same as unnamed_data_stream_size, then the stream is
245 * uncompressed. If this is the *not* the same as
246 * unnamed_data_stream_size, then the stream is compressed. */
247 le64 unnamed_data_stream_size_in_wim;
249 /* Byte offset of the file's unnamed data stream in the WIM. */
250 le64 unnamed_data_stream_offset_in_wim;
253 /* WIM-specific information about a WIM data source */
254 struct WimOverlay_dat_entry_1 {
256 /* Identifier for the WIM data source, (normally allocated by
257 * FSCTL_ADD_OVERLAY). Every 'WimOverlay_dat_entry_1' should have a
258 * different value for this. */
261 /* Byte offset, from the beginning of the file, of the corresponding
262 * 'struct WimOverlay_dat_entry_2' for this WIM data source. */
265 /* Size, in bytes, of the corresponding 'struct WimOverlay_dat_entry_2
266 * for this WIM data source, including wim_file_name and its null
270 /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM. */
273 /* Index of the image in the WIM to use??? (This doesn't really make
274 * sense, since WIM files combine file data "blobs" for all images into
275 * a single table. Set to 1 if unsure...) */
278 /* GUID of the WIM file (copied from the WIM header, offset +0x18). */
283 * Format of file: "\System Volume Information\WimOverlay.dat"
285 * Not documented by Microsoft.
287 * The file consists of a 'struct WimOverlay_dat_header' followed by one or more
288 * 'struct WimOverlay_dat_entry_1', followed by the same number of 'struct
289 * WimOverlay_dat_entry_2'. Note that 'struct WimOverlay_dat_entry_1' is of
290 * fixed length, whereas 'struct WimOverlay_dat_entry_2' is of variable length.
292 struct WimOverlay_dat_header {
293 /* Set to WIMOVERLAY_DAT_MAGIC */
295 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
297 /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION) */
298 le32 wim_provider_version;
300 /* Set to 0x00000028 */
303 /* Set to number of WIMs registered (listed in the file) */
306 /* The next available data source ID. This is tracked so that data
307 * source IDs are never reused, even if a WIM is unregistered. */
308 le64 next_data_source_id;
310 struct WimOverlay_dat_entry_1 entry_1s[];
313 /* Location information about a WIM data source */
314 struct WimOverlay_dat_entry_2 {
321 /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
322 * wim_file_name and its null terminator. */
335 /* Size of this inner structure, in bytes. */
336 le32 inner_struct_size;
353 /*************************
354 * Partition information
355 ************************/
357 /* Partition identifier */
359 /* (For MBR-formatted disks) */
361 /* Offset, in bytes, of the MBR partition, from
362 * the beginning of the disk. */
363 le64 part_start_offset;
369 /* (For GPT-formatted disks) */
371 /* Unique GUID of the GPT partition */
372 u8 part_unique_guid[16];
379 /***********************
381 **********************/
383 /* 1 for MBR, 0 for GPT */
384 le32 partition_table_type;
385 #define WIMOVERLAY_PARTITION_TYPE_MBR 1
386 #define WIMOVERLAY_PARTITION_TYPE_GPT 0
388 /* Disk identifier */
390 /* (For MBR-formatted disks) */
392 /* 4-byte ID of the MBR disk */
399 /* (For GPT-formatted disks) */
401 /* GUID of the GPT disk */
406 /* Set to 0. (This is the right size for some sort of optional
408 le32 unknown_0x58[4];
410 /**************************
411 * Location in filesystem
412 *************************/
414 /* Null-terminated path to WIM file. Begins with \ but does
415 * *not* include drive letter! */
416 utf16lechar wim_file_name[];
420 static _unused_attribute void
421 wof_check_structs(void)
423 STATIC_ASSERT(sizeof(struct WimOverlay_dat_header) == 24);
424 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_1) == 40);
425 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_2) == 104);
428 #endif /* __WIN32__ */