]> wimlib.net Git - wimlib/blob - include/wimlib/wof.h
mount_image.c: add fallback definitions of RENAME_* constants
[wimlib] / include / wimlib / wof.h
1 /*
2  * wof.h
3  *
4  * Definitions for the Windows Overlay Filesystem filter (WOF) ioctls, as well
5  * some definitions for associated undocumented data structures.
6  *
7  * The following copying information applies to this specific source code file:
8  *
9  * Written in 2014-2021 by Eric Biggers <ebiggers3@gmail.com>
10  *
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").
15  *
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.
19  *
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/>.
22  */
23
24 #ifndef _WOF_H_
25 #define _WOF_H_
26
27 #include "wimlib/compiler.h"
28 #include "wimlib/types.h"
29
30 /*
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.
35  *
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:
39  *
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
45  *
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.
49  *
50  * WOF provides various ioctls that control its operation.  For example,
51  * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
52  *
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.
59  *
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.
62  */
63
64
65 /*----------------------------------------------------------------------------*
66  *                          WOF ioctl definitions                             *
67  *----------------------------------------------------------------------------*/
68
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
74         DWORD Version;
75         DWORD Provider;
76 } WOF_EXTERNAL_INFO, *PWOF_EXTERNAL_INFO;
77 #endif /* WOF_CURRENT_VERSION */
78
79 /* WIM provider ("WIMBoot") */
80 #ifndef WOF_PROVIDER_WIM
81 #define WOF_PROVIDER_WIM 1
82 /*
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
86  */
87 typedef struct _WIM_PROVIDER_EXTERNAL_INFO {
88 #define WIM_PROVIDER_CURRENT_VERSION 1
89         ULONG         Version;
90         ULONG         Flags;
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 */
96
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
104         DWORD Version;
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
109         DWORD Algorithm;
110         DWORD Flags;
111 } FILE_PROVIDER_EXTERNAL_INFO_V1, *PFILE_PROVIDER_EXTERNAL_INFO_V1;
112 #endif /* WOF_PROVIDER_FILE */
113
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)
119 #endif
120
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)
126 #endif
127
128 #ifndef STATUS_OBJECT_NOT_EXTERNALLY_BACKED
129 #define STATUS_OBJECT_NOT_EXTERNALLY_BACKED     0xC000046D
130 #endif
131
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)
137 #endif
138
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)
144 #endif
145
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;
154         GUID WimGuid;
155         ULONG WimFileNameOffset;
156         ULONG WimType;
157         ULONG WimIndex;
158         ULONG Flags;
159 } WIM_PROVIDER_OVERLAY_ENTRY, *PWIM_PROVIDER_OVERLAY_ENTRY;
160 #endif /* FSCTL_ENUM_OVERLAY */
161
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
170         ULONG WimType;
171         ULONG WimIndex;
172         ULONG WimFileNameOffset;
173         ULONG WimFileNameLength;
174 } WIM_PROVIDER_ADD_OVERLAY_INPUT, *PWIM_PROVIDER_ADD_OVERLAY_INPUT;
175 #endif /* FSCTL_ADD_OVERLAY */
176
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 */
186
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 */
198
199 /*----------------------------------------------------------------------------*
200  *        WOF reparse point and WimOverlay.dat structs (undocumented)         *
201  *----------------------------------------------------------------------------*/
202
203 /*
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.)
208  *
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.
212  */
213 struct wim_provider_rpdata {
214         /* Set to 2.  Uncertain meaning.  */
215         le32 version;
216
217         /* 0 when WIM provider active, otherwise
218          * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
219          * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED.  */
220         le32 flags;
221
222         /* Integer ID that identifies the WIM.  */
223         le64 data_source_id;
224
225         /* SHA-1 message digest of the file's unnamed data stream.  */
226         u8 unnamed_data_stream_hash[20];
227
228         /* SHA-1 message digest of the WIM's blob table as stored on disk.  */
229         u8 blob_table_hash[20];
230
231         /* Uncompressed size of the file's unnamed data stream, in bytes.  */
232         le64 unnamed_data_stream_size;
233
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;
239
240         /* Byte offset of the file's unnamed data stream in the WIM.  */
241         le64 unnamed_data_stream_offset_in_wim;
242 } _packed_attribute;
243
244 /* WIM-specific information about a WIM data source  */
245 struct WimOverlay_dat_entry_1 {
246
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.  */
250         le64 data_source_id;
251
252         /* Byte offset, from the beginning of the file, of the corresponding
253          * 'struct WimOverlay_dat_entry_2' for this WIM data source.  */
254         le32 entry_2_offset;
255
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
258          * terminator.  */
259         le32 entry_2_length;
260
261         /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM.  */
262         le32 wim_type;
263
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...)  */
267         le32 wim_index;
268
269         /* GUID of the WIM file (copied from the WIM header, offset +0x18).  */
270         u8 guid[16];
271 } _packed_attribute;
272
273 /*
274  * Format of file: "\System Volume Information\WimOverlay.dat"
275  *
276  * Not documented by Microsoft.
277  *
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.
282  */
283 struct WimOverlay_dat_header {
284         /* Set to WIMOVERLAY_DAT_MAGIC  */
285         le32 magic;
286 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
287
288         /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION)  */
289         le32 wim_provider_version;
290
291         /* Set to 0x00000028  */
292         le32 unknown_0x08;
293
294         /* Set to number of WIMs registered (listed in the file)  */
295         le32 num_entries;
296
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;
300
301         struct WimOverlay_dat_entry_1 entry_1s[];
302 } _packed_attribute;
303
304 /* Location information about a WIM data source  */
305 struct WimOverlay_dat_entry_2 {
306         /* Set to 0  */
307         le32 unknown_0x00;
308
309         /* Set to 0  */
310         le32 unknown_0x04;
311
312         /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
313          * wim_file_name and its null terminator.  */
314         le32 entry_2_length;
315
316         /* Set to 0  */
317         le32 unknown_0x0C;
318
319         /* Set to 5  */
320         le32 unknown_0x10;
321
322         struct {
323                 /* Set to 1  */
324                 le32 unknown_0x14;
325
326                 /* Size of this inner structure, in bytes.  */
327                 le32 inner_struct_size;
328
329                 /* Set to 5  */
330                 le32 unknown_0x1C;
331
332                 /* Set to 6  */
333                 le32 unknown_0x20;
334
335                 /* Set to 0  */
336                 le32 unknown_0x24;
337
338                 /* Set to 0x48  */
339                 le32 unknown_0x28;
340
341                 /* Set to 0  */
342                 le32 unknown_0x2C;
343
344                 /*************************
345                  * Partition information
346                  ************************/
347
348                 /* Partition identifier  */
349                 union {
350                         /* (For MBR-formatted disks)  */
351                         struct {
352                                 /* Offset, in bytes, of the MBR partition, from
353                                  * the beginning of the disk.  */
354                                 le64 part_start_offset;
355
356                                 /* Set to 0  */
357                                 le64 padding;
358                         } mbr;
359
360                         /* (For GPT-formatted disks)  */
361                         struct {
362                                 /* Unique GUID of the GPT partition  */
363                                 u8 part_unique_guid[16];
364                         } gpt;
365                 } partition;
366
367                 /* Set to 0  */
368                 le32 unknown_0x40;
369
370                 /***********************
371                  * Disk information
372                  **********************/
373
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
378
379                 /* Disk identifier  */
380                 union {
381                         /* (For MBR-formatted disks)  */
382                         struct {
383                                 /* 4-byte ID of the MBR disk  */
384                                 le32 disk_id;
385
386                                 /* Set to 0  */
387                                 le32 padding[3];
388                         } mbr;
389
390                         /* (For GPT-formatted disks)  */
391                         struct {
392                                 /* GUID of the GPT disk  */
393                                 u8 disk_guid[16];
394                         } gpt;
395                 } disk;
396
397                 /* Set to 0.  (This is the right size for some sort of optional
398                  * GUID...)  */
399                 le32 unknown_0x58[4];
400
401                 /**************************
402                  * Location in filesystem
403                  *************************/
404
405                 /* Null-terminated path to WIM file.  Begins with \ but does
406                  * *not* include drive letter!  */
407                 utf16lechar wim_file_name[];
408         } _packed_attribute;
409 } _packed_attribute;
410
411 static _unused_attribute void
412 wof_check_structs(void)
413 {
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);
417 }
418
419 #endif /* _WOF_H_ */