]> 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  * Copyright 2022 Eric Biggers
8  *
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
16  * conditions:
17  *
18  * The above copyright notice and this permission notice shall be
19  * included in all copies or substantial portions of the Software.
20  *
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.
29  */
30
31 #ifndef _WOF_H_
32 #define _WOF_H_
33
34 #include "wimlib/compiler.h"
35 #include "wimlib/types.h"
36
37 #ifdef _WIN32
38
39 /*
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.
44  *
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:
48  *
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
54  *
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.
58  *
59  * WOF provides various ioctls that control its operation.  For example,
60  * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
61  *
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.
68  *
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.
71  */
72
73
74 /*----------------------------------------------------------------------------*
75  *                          WOF ioctl definitions                             *
76  *----------------------------------------------------------------------------*/
77
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
83         DWORD Version;
84         DWORD Provider;
85 } WOF_EXTERNAL_INFO, *PWOF_EXTERNAL_INFO;
86 #endif /* WOF_CURRENT_VERSION */
87
88 /* WIM provider ("WIMBoot") */
89 #ifndef WOF_PROVIDER_WIM
90 #define WOF_PROVIDER_WIM 1
91 /*
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
95  */
96 typedef struct _WIM_PROVIDER_EXTERNAL_INFO {
97 #define WIM_PROVIDER_CURRENT_VERSION 1
98         ULONG         Version;
99         ULONG         Flags;
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 */
105
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
113         DWORD Version;
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
118         DWORD Algorithm;
119         DWORD Flags;
120 } FILE_PROVIDER_EXTERNAL_INFO_V1, *PFILE_PROVIDER_EXTERNAL_INFO_V1;
121 #endif /* WOF_PROVIDER_FILE */
122
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)
128 #endif
129
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)
135 #endif
136
137 #ifndef STATUS_OBJECT_NOT_EXTERNALLY_BACKED
138 #define STATUS_OBJECT_NOT_EXTERNALLY_BACKED     0xC000046D
139 #endif
140
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)
146 #endif
147
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)
153 #endif
154
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)
160 #endif
161 typedef struct _WIM_PROVIDER_OVERLAY_ENTRY {
162         ULONG NextEntryOffset;
163         LARGE_INTEGER DataSourceId;
164         GUID WimGuid;
165         ULONG WimFileNameOffset;
166         ULONG WimType;
167         ULONG WimIndex;
168         ULONG Flags;
169 } WIM_PROVIDER_OVERLAY_ENTRY, *PWIM_PROVIDER_OVERLAY_ENTRY;
170
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)
176 #endif
177 typedef struct _WIM_PROVIDER_ADD_OVERLAY_INPUT {
178 #define WIM_BOOT_NOT_OS_WIM     0
179 #define WIM_BOOT_OS_WIM         1
180         ULONG WimType;
181         ULONG WimIndex;
182         ULONG WimFileNameOffset;
183         ULONG WimFileNameLength;
184 } WIM_PROVIDER_ADD_OVERLAY_INPUT, *PWIM_PROVIDER_ADD_OVERLAY_INPUT;
185
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)
191 #endif
192 typedef struct _WIM_PROVIDER_REMOVE_OVERLAY_INPUT {
193         LARGE_INTEGER DataSourceId;
194 } WIM_PROVIDER_REMOVE_OVERLAY_INPUT, *PWIM_PROVIDER_REMOVE_OVERLAY_INPUT;
195
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)
201 #endif
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;
207
208 /*----------------------------------------------------------------------------*
209  *        WOF reparse point and WimOverlay.dat structs (undocumented)         *
210  *----------------------------------------------------------------------------*/
211
212 /*
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.)
217  *
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.
221  */
222 struct wim_provider_rpdata {
223         /* Set to 2.  Uncertain meaning.  */
224         le32 version;
225
226         /* 0 when WIM provider active, otherwise
227          * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
228          * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED.  */
229         le32 flags;
230
231         /* Integer ID that identifies the WIM.  */
232         le64 data_source_id;
233
234         /* SHA-1 message digest of the file's unnamed data stream.  */
235         u8 unnamed_data_stream_hash[20];
236
237         /* SHA-1 message digest of the WIM's blob table as stored on disk.  */
238         u8 blob_table_hash[20];
239
240         /* Uncompressed size of the file's unnamed data stream, in bytes.  */
241         le64 unnamed_data_stream_size;
242
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;
248
249         /* Byte offset of the file's unnamed data stream in the WIM.  */
250         le64 unnamed_data_stream_offset_in_wim;
251 } __attribute__((packed));
252
253 /* WIM-specific information about a WIM data source  */
254 struct WimOverlay_dat_entry_1 {
255
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.  */
259         le64 data_source_id;
260
261         /* Byte offset, from the beginning of the file, of the corresponding
262          * 'struct WimOverlay_dat_entry_2' for this WIM data source.  */
263         le32 entry_2_offset;
264
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
267          * terminator.  */
268         le32 entry_2_length;
269
270         /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM.  */
271         le32 wim_type;
272
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...)  */
276         le32 wim_index;
277
278         /* GUID of the WIM file (copied from the WIM header, offset +0x18).  */
279         u8 guid[16];
280 } __attribute__((packed));
281
282 /*
283  * Format of file: "\System Volume Information\WimOverlay.dat"
284  *
285  * Not documented by Microsoft.
286  *
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.
291  */
292 struct WimOverlay_dat_header {
293         /* Set to WIMOVERLAY_DAT_MAGIC  */
294         le32 magic;
295 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
296
297         /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION)  */
298         le32 wim_provider_version;
299
300         /* Set to 0x00000028  */
301         le32 unknown_0x08;
302
303         /* Set to number of WIMs registered (listed in the file)  */
304         le32 num_entries;
305
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;
309
310         struct WimOverlay_dat_entry_1 entry_1s[];
311 } __attribute__((packed));
312
313 /* Location information about a WIM data source  */
314 struct WimOverlay_dat_entry_2 {
315         /* Set to 0  */
316         le32 unknown_0x00;
317
318         /* Set to 0  */
319         le32 unknown_0x04;
320
321         /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
322          * wim_file_name and its null terminator.  */
323         le32 entry_2_length;
324
325         /* Set to 0  */
326         le32 unknown_0x0C;
327
328         /* Set to 5  */
329         le32 unknown_0x10;
330
331         struct {
332                 /* Set to 1  */
333                 le32 unknown_0x14;
334
335                 /* Size of this inner structure, in bytes.  */
336                 le32 inner_struct_size;
337
338                 /* Set to 5  */
339                 le32 unknown_0x1C;
340
341                 /* Set to 6  */
342                 le32 unknown_0x20;
343
344                 /* Set to 0  */
345                 le32 unknown_0x24;
346
347                 /* Set to 0x48  */
348                 le32 unknown_0x28;
349
350                 /* Set to 0  */
351                 le32 unknown_0x2C;
352
353                 /*************************
354                  * Partition information
355                  ************************/
356
357                 /* Partition identifier  */
358                 union {
359                         /* (For MBR-formatted disks)  */
360                         struct {
361                                 /* Offset, in bytes, of the MBR partition, from
362                                  * the beginning of the disk.  */
363                                 le64 part_start_offset;
364
365                                 /* Set to 0  */
366                                 le64 padding;
367                         } mbr;
368
369                         /* (For GPT-formatted disks)  */
370                         struct {
371                                 /* Unique GUID of the GPT partition  */
372                                 u8 part_unique_guid[16];
373                         } gpt;
374                 } partition;
375
376                 /* Set to 0  */
377                 le32 unknown_0x40;
378
379                 /***********************
380                  * Disk information
381                  **********************/
382
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
387
388                 /* Disk identifier  */
389                 union {
390                         /* (For MBR-formatted disks)  */
391                         struct {
392                                 /* 4-byte ID of the MBR disk  */
393                                 le32 disk_id;
394
395                                 /* Set to 0  */
396                                 le32 padding[3];
397                         } mbr;
398
399                         /* (For GPT-formatted disks)  */
400                         struct {
401                                 /* GUID of the GPT disk  */
402                                 u8 disk_guid[16];
403                         } gpt;
404                 } disk;
405
406                 /* Set to 0.  (This is the right size for some sort of optional
407                  * GUID...)  */
408                 le32 unknown_0x58[4];
409
410                 /**************************
411                  * Location in filesystem
412                  *************************/
413
414                 /* Null-terminated path to WIM file.  Begins with \ but does
415                  * *not* include drive letter!  */
416                 utf16lechar wim_file_name[];
417         } __attribute__((packed));
418 } __attribute__((packed));
419
420 static void __attribute__((unused))
421 wof_check_structs(void)
422 {
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);
426 }
427
428 #endif /* _WIN32 */
429
430 #endif /* _WOF_H_ */