4 * Definitions for the Windows Overlay File System Filter (WOF) ioctls, as well
5 * some definitions for associated undocumented data structures. See
6 * http://msdn.microsoft.com/en-us/library/windows/hardware/ff540367(v=vs.85).aspx
7 * for more information about the documented ioctls.
9 * The author dedicates this file to the public domain.
10 * You can do whatever you want with this file.
16 #include "wimlib/compiler.h"
17 #include "wimlib/types.h"
20 * The Windows Overlay FileSystem Filter (WOF, a.k.a. wof.sys) is a filesystem
21 * filter driver, available in Windows 8.1 and later, which allows files to be
22 * "externally backed", meaning that their data is stored in another location,
23 * possibly in compressed form.
25 * WOF implements a plug-in mechanism by which a specific "provider" is
26 * responsible for actually externally backing a given file. The currently
27 * known providers are:
29 * - The WIM provider: allows a file to be externally backed by a
30 * compressed resource in a WIM archive
31 * - The file provider: allows a file to be "externally backed" by a named
32 * data stream stored with the file itself, where that named data stream
33 * has the format of a compressed WIM resource
35 * For both of these providers, externally backed files are effectively
36 * read-only. If you try to write to such a file, Windows automatically
37 * decompresses it and turns it into a regular, non-externally-backed file.
39 * WOF provides various ioctls that control its operation. For example,
40 * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
42 * WOF external backings are implemented using reparse points. One consequence
43 * of this is that WOF external backings can only be set on files that do not
44 * already have a reparse point set. Another consequence of this is that it is
45 * possible to create a WOF external backing by manually creating the reparse
46 * point, although this requires dealing with undocumented data structures and
47 * it only works when the WOF driver is not currently attached to the volume.
49 * Note that only the unnamed data stream portion of a file can be externally
50 * backed. Other NTFS streams and metadata are not externally backed.
54 /* Current version of the WOF driver/protocol */
55 #define WOF_CURRENT_VERSION 1
57 /* Specifies the WIM backing provider */
58 #define WOF_PROVIDER_WIM 1
60 /* Specifies the "file" backing provider (a.k.a. System Compression) */
61 #define WOF_PROVIDER_FILE 2
63 /* The current version of the WIM backing provider */
64 #define WIM_PROVIDER_CURRENT_VERSION 1
66 /* The current version of the file backing provider */
67 #define FILE_PROVIDER_CURRENT_VERSION 1
69 /* Identifies a backing provider for a specific overlay service version. */
70 struct wof_external_info {
72 /* Version of the overlay service supported by the backing provider.
73 * Set to WOF_CURRENT_VERSION. */
76 /* Identifier for the backing provider. Example value:
77 * WOF_PROVIDER_WIM. */
83 * Format of the WIM provider reparse data. This is the data which follows the
84 * portion of the reparse point common to WOF. (The common portion consists of
85 * a reparse point header where the reparse tag is 0x80000017, then a 'struct
86 * wof_external_info' which specifies the provider.)
88 * Note that Microsoft does not document any of the reparse point formats for
89 * WOF, although they document the structures which must be passed into the
90 * ioctls, which are often similar.
92 struct wim_provider_rpdata {
93 /* Set to 2. Uncertain meaning. */
96 /* 0 when WIM provider active, otherwise
97 * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
98 * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
101 /* Integer ID that identifies the WIM. */
104 /* SHA-1 message digest of the file's unnamed data stream. */
105 u8 unnamed_data_stream_hash[20];
107 /* SHA-1 message digest of the WIM's blob table as stored on disk. */
108 u8 blob_table_hash[20];
110 /* Uncompressed size of the file's unnamed data stream, in bytes. */
111 le64 unnamed_data_stream_size;
113 /* Size of the file's unnamed data stream as stored in the WIM file.
114 * If this is the same as unnamed_data_stream_size, then the stream is
115 * uncompressed. If this is the *not* the same as
116 * unnamed_data_stream_size, then the stream is compressed. */
117 le64 unnamed_data_stream_size_in_wim;
119 /* Byte offset of the file's unnamed data stream in the WIM. */
120 le64 unnamed_data_stream_offset_in_wim;
123 /* WIM-specific information about a WIM data source */
124 struct WimOverlay_dat_entry_1 {
126 /* Identifier for the WIM data source, (normally allocated by
127 * FSCTL_ADD_OVERLAY). Every 'WimOverlay_dat_entry_1' should have a
128 * different value for this. */
131 /* Byte offset, from the beginning of the file, of the corresponding
132 * 'struct WimOverlay_dat_entry_2' for this WIM data source. */
135 /* Size, in bytes, of the corresponding 'struct WimOverlay_dat_entry_2
136 * for this WIM data source, including wim_file_name and its null
140 /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM. */
143 /* Index of the image in the WIM to use??? (This doesn't really make
144 * sense, since WIM files combine file data "blobs" for all images into
145 * a single table. Set to 1 if unsure...) */
148 /* GUID of the WIM file (copied from the WIM header, offset +0x18). */
153 * Format of file: "\System Volume Information\WimOverlay.dat"
155 * Not documented by Microsoft.
157 * The file consists of a 'struct WimOverlay_dat_header' followed by one or more
158 * 'struct WimOverlay_dat_entry_1', followed by the same number of 'struct
159 * WimOverlay_dat_entry_2'. Note that 'struct WimOverlay_dat_entry_1' is of
160 * fixed length, whereas 'struct WimOverlay_dat_entry_2' is of variable length.
162 struct WimOverlay_dat_header {
163 /* Set to WIMOVERLAY_DAT_MAGIC */
165 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
167 /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION) */
168 le32 wim_provider_version;
170 /* Set to 0x00000028 */
173 /* Set to number of WIMs registered (listed in the file) */
176 /* The next available data source ID. This is tracked so that data
177 * source IDs are never reused, even if a WIM is unregistered. */
178 le64 next_data_source_id;
180 struct WimOverlay_dat_entry_1 entry_1s[];
183 /* Location information about a WIM data source */
184 struct WimOverlay_dat_entry_2 {
191 /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
192 * wim_file_name and its null terminator. */
205 /* Size of this inner structure, in bytes. */
206 le32 inner_struct_size;
223 /*************************
224 * Partition information
225 ************************/
227 /* Partition identifier */
229 /* (For MBR-formatted disks) */
231 /* Offset, in bytes, of the MBR partition, from
232 * the beginning of the disk. */
233 le64 part_start_offset;
239 /* (For GPT-formatted disks) */
241 /* Unique GUID of the GPT partition */
242 u8 part_unique_guid[16];
249 /***********************
251 **********************/
253 /* 1 for MBR, 0 for GPT */
254 le32 partition_table_type;
255 #define WIMOVERLAY_PARTITION_TYPE_MBR 1
256 #define WIMOVERLAY_PARTITION_TYPE_GPT 0
258 /* Disk identifier */
260 /* (For MBR-formatted disks) */
262 /* 4-byte ID of the MBR disk */
269 /* (For GPT-formatted disks) */
271 /* GUID of the GPT disk */
276 /* Set to 0. (This is the right size for some sort of optional
278 le32 unknown_0x58[4];
280 /**************************
281 * Location in filesystem
282 *************************/
284 /* Null-terminated path to WIM file. Begins with \ but does
285 * *not* include drive letter! */
286 utf16lechar wim_file_name[];
290 static _unused_attribute void
291 wof_check_structs(void)
293 STATIC_ASSERT(sizeof(struct WimOverlay_dat_header) == 24);
294 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_1) == 40);
295 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_2) == 104);
298 /*****************************************************************************
300 * --- FSCTL_SET_EXTERNAL_BACKING ---
302 * Sets the backing source of a file.
304 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
305 * Access: 0 (FILE_ANY_ACCESS)
307 * Method: 0 (METHOD_BUFFERED)
309 * Input buffer: 'struct wof_external_info' followed by provider-specific data
310 * ('struct wim_provider_external_info' in the case of WIM).
312 * Output buffer: None
314 #define FSCTL_SET_EXTERNAL_BACKING 0x9030C
316 struct wim_provider_external_info {
318 /* Set to WIM_PROVIDER_CURRENT_VERSION. */
321 /* 0 when WIM provider active, otherwise
322 * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
323 * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
326 /* Integer ID that identifies the WIM. Get this with the
327 * FSCTL_ADD_OVERLAY ioctl. */
330 /* SHA-1 message digest of the file's unnamed data stream. */
331 u8 unnamed_data_stream_hash[20];
334 struct file_provider_external_info {
336 /* Set to FILE_PROVIDER_CURRENT_VERSION. */
339 u32 compression_format;
340 #define FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K 0
341 #define FILE_PROVIDER_COMPRESSION_FORMAT_LZX 1
342 #define FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS8K 2
343 #define FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS16K 3
346 /*****************************************************************************
348 * --- FSCTL_GET_EXTERNAL_BACKING ---
350 * Get external backing information for the specified file.
352 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
353 * Access: 0 (FILE_ANY_ACCESS)
355 * Method: 0 (METHOD_BUFFERED)
358 * Output buffer: 'struct wof_external_info' followed by provider-specific data
359 * ('struct wim_provider_external_info' in the case of WIM).
361 #define FSCTL_GET_EXTERNAL_BACKING 0x90310
363 #define STATUS_OBJECT_NOT_EXTERNALLY_BACKED 0xC000046D
365 /*****************************************************************************
367 * --- FSCTL_DELETE_EXTERNAL_BACKING ---
369 * Copy a file from its backing source to its volume, then disassociate it from
370 * its backing provider.
372 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
373 * Access: 0 (FILE_ANY_ACCESS)
375 * Method: 0 (METHOD_BUFFERED)
378 * Output buffer: None
380 #define FSCTL_DELETE_EXTERNAL_BACKING 0x90314
382 /*****************************************************************************
384 * --- FSCTL_ENUM_EXTERNAL_BACKING ---
386 * Enumerate externally backed files on a volume.
388 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
389 * Access: 0 (FILE_ANY_ACCESS)
391 * Method: 0 (METHOD_BUFFERED)
394 * Output buffer: A 16-byte buffer that receives the 128-bit file ID for the
395 * next externally backed file.
397 * The handle used may be either the volume handle or the handle for any file or
398 * directory on the volume.
400 * When all externally backed files on the volume have been enumerated, the
401 * function fails with ERROR_NO_MORE_FILES.
403 #define FSCTL_ENUM_EXTERNAL_BACKING 0x90318
405 /*****************************************************************************
407 * --- FSCTL_ENUM_OVERLAY ---
409 * Enumerates the volume's overlay sources from the specified provider.
411 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
412 * Access: 0 (FILE_ANY_ACCESS)
414 * Method: 3 (METHOD_NEITHER)
416 * Input buffer: 'struct wof_external_info' to specify the provider for which
417 * to enumerate the overlay sources.
419 * Output buffer: Provider-specific data. For the WIM provider, an array of
420 * 'struct wim_provider_overlay_entry'.
422 * This ioctl must be performed on the volume handle, such as \\.\C:
424 #define FSCTL_ENUM_OVERLAY 0x9031F
426 struct wim_provider_overlay_entry {
427 /* Byte offset of the next entry from the beginning of this structure,
428 * or 0 if there are no more entries. */
429 u32 next_entry_offset;
433 /* Identifier for the WIM file. */
436 /* GUID of the WIM file. */
439 /* Byte offset of the WIM's file name from the beginning of this
441 u32 wim_file_name_offset;
443 /* Type of WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM. */
446 /* Index of the image in the WIM to use??? (This doesn't really make
447 * sense, since WIM files combine file data "blobs" for all images into
448 * a single table. Set to 1 if unsure...) */
451 /* 0 when WIM provider active, otherwise
452 * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
453 * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
456 /* Full path to the WIM in the NT device namespace, e.g.
457 * "\Device\HardDiskVolume2\test.wim". Seems to be null-terminated,
458 * although you probably shouldn't assume so. */
459 wchar_t wim_file_name[];
463 /*****************************************************************************
465 * --- FSCTL_ADD_OVERLAY ---
467 * Adds a new external backing source to a volume.
469 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
470 * Access: 2 (FILE_WRITE_ACCESS)
472 * Method: 0 (METHOD_BUFFERED)
474 * Input buffer: 'struct wof_external_info' followed by provider-specific data
475 * ('struct wim_provider_add_overlay_input' in the case of WIM).
477 * Output buffer: Buffer large enough to receive any information resulting from
478 * the add operation. For the WIM provider, this must be an 8 byte buffer that
479 * receives the 64-bit WIM file ID.
481 * This ioctl must be performed on the volume handle, such as \\.\C:
483 #define FSCTL_ADD_OVERLAY 0x98330
485 struct wim_provider_add_overlay_input {
487 /* Type of WIM file. */
489 #define WIM_BOOT_OS_WIM 0
490 #define WIM_BOOT_NOT_OS_WIM 1
492 /* Index of the image in the WIM to use??? (This doesn't really make
493 * sense, since WIM files combine file data "blobs" for all images into
494 * a single table. Set to 1 if unsure...) */
497 /* Byte offset of wim_file_name in this buffer, not including the
498 * preceding 'struct wof_external_info' (should be 16). */
499 u32 wim_file_name_offset;
501 /* Number of bytes in wim_file_name. */
502 u32 wim_file_name_length;
504 /* Full path to the WIM, e.g. "\??\C:\test-wimboot.wim".
505 * Does NOT need to be null terminated (MS docs claim otherwise). */
506 wchar_t wim_file_name[];
509 /*****************************************************************************
511 * --- FSCTL_REMOVE_OVERLAY ---
513 * Removes an external backing source from a volume.
515 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
516 * Access: 2 (FILE_WRITE_ACCESS)
518 * Method: 0 (METHOD_BUFFERED)
520 * Input buffer: 'struct wof_external_info' followed by provider-specific data
521 * ('struct wim_provider_remove_overlay_input' in the case of WIM).
523 * Output buffer: None
525 * This ioctl must be performed on the volume handle, such as \\.\C:
527 #define FSCTL_REMOVE_OVERLAY 0x98334
529 struct wim_provider_remove_overlay_input {
530 /* Integer ID that identifies the WIM. */
535 /*****************************************************************************
537 * --- FSCTL_UPDATE_OVERLAY ---
539 * Updates an overlay source for a volume.
541 * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
542 * Access: 2 (FILE_WRITE_ACCESS)
544 * Method: 0 (METHOD_BUFFERED)
546 * Input buffer: 'struct wof_external_info' followed by provider-specific data
547 * ('struct wim_provider_update_overlay_input' in the case of WIM).
549 * Output buffer: None
551 * This ioctl must be performed on the volume handle, such as \\.\C:
553 #define FSCTL_UPDATE_OVERLAY 0x98338
555 struct wim_provider_update_overlay_input {
556 /* Integer ID that identifies the WIM data source. */
559 /* Byte offset of wim_file_name in this buffer, not including the
560 * preceding 'struct wof_external_info' (should be 16). */
561 u32 wim_file_name_offset;
563 /* Number of bytes in wim_file_name. */
564 u32 wim_file_name_length;
566 /* Full path to the WIM, e.g. "\??\C:\test-wimboot.wim".
567 * Does NOT need to be null terminated (MS docs claim otherwise).
568 * This WIM must be renamed from the original WIM, or at least be an
569 * identical copy of it! (Maybe the WIM's GUID field is checked.) */
570 wchar_t wim_file_name[];