Place headers that could be useful in unrelated projects in public domain
[wimlib] / include / wimlib / wof.h
1 /*
2  * wof.h
3  *
4  * Definitions for Windows Overlay File System Filter (WOF) ioctls.  See
5  * http://msdn.microsoft.com/en-us/library/windows/hardware/ff540367(v=vs.85).aspx
6  * for more information.
7  *
8  * The author dedicates this file to the public domain.
9  * You can do whatever you want with this file.
10  */
11
12 #ifndef _WOF_H_
13 #define _WOF_H_
14
15 #include "wimlib/types.h"
16 #include "wimlib/compiler.h"
17
18 #define WOF_CURRENT_VERSION     1
19 #define WOF_PROVIDER_WIM        1
20 #define WIM_PROVIDER_CURRENT_VERSION 1
21
22 /* Identifies a backing provider for a specific overlay service version.  */
23 struct wof_external_info {
24
25         /* Version of the overlay service supported by the backing provider.
26          * Set to WOF_CURRENT_VERSION.  */
27         u32 version;
28
29         /* Identifier for the backing provider.  Example value:
30          * WOF_PROVIDER_WIM.  */
31         u32 provider;
32 };
33
34 /* On Windows, WOF reparse points can only be directly created when the WOF
35  * driver is NOT running on the volume.  Otherwise, the WOF ioctl
36  * (FSCTL_SET_EXTERNAL_BACKING, FSCTL_GET_EXTERNAL_BACKING,
37  * FSCTL_DELETE_EXTERNAL_BACKING) must be used instead.  */
38
39 /*
40  * Format of the reparse data of WoF (Windows Overlay File System Filter)
41  * reparse points.  These include WIMBoot "pointer files".
42  *
43  * This is not documented by Microsoft!!!
44  *
45  * Notes:
46  *      - 'struct wim_provider_rpdata' must be preceded by
47  *        'struct wof_external_info'.
48  *      - Reparse tag is 0x80000017
49  *      - Don't make these if the file has no unnamed data stream, has an empty
50  *        unnamed data stream, or already is a reparse point.
51  *      - There is nowhere to put named data streams.  They have to copied
52  *        literally to the reparse point file.
53  */
54 struct wim_provider_rpdata {
55         /* Set to 2.  Uncertain meaning.  */
56         le32 version;
57
58         /* 0 when WIM provider active, otherwise
59          * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
60          * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED.  */
61         le32 flags;
62
63         /* Integer ID that identifies the WIM.  */
64         le64 data_source_id;
65
66         /* SHA1 message digest of the file's unnamed data stream.  */
67         u8 resource_hash[20];
68
69         /* SHA1 message digest of the WIM's lookup table.  */
70         u8 wim_lookup_table_hash[20];
71
72         /* Uncompressed size of the file's unnamed data stream, in bytes.  */
73         le64 stream_uncompressed_size;
74
75         /* Compressed size of the file's unnamed data stream, in bytes.  If
76          * stream is stored uncompressed, set this the same as the uncompressed
77          * size.  */
78         le64 stream_compressed_size;
79
80         /* Byte offset of the file's unnamed data stream in the WIM.  */
81         le64 stream_offset_in_wim;
82 } _packed_attribute;
83
84 /* WIM-specific information about a WIM data source  */
85 struct WimOverlay_dat_entry_1 {
86
87         /* Identifier for the WIM data source, (normally allocated by
88          * FSCTL_ADD_OVERLAY).  Every 'WimOverlay_dat_entry_1' should have a
89          * different value for this.  */
90         le64 data_source_id;
91
92         /* Byte offset, from the beginning of the file, of the corresponding
93          * 'struct WimOverlay_dat_entry_2' for this WIM data source.  */
94         le32 entry_2_offset;
95
96         /* Size, in bytes, of the corresponding 'struct WimOverlay_dat_entry_2
97          * for this WIM data source, including wim_file_name and its null
98          * terminator.  */
99         le32 entry_2_length;
100
101         /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM.  */
102         le32 wim_type;
103
104         /* Index of the image in the WIM to use??? (This doesn't really make
105          * sense, since WIM files combine streams for all images into a single
106          * table.  Set to 1 if unsure...)  */
107         le32 wim_index;
108
109         /* GUID of the WIM file (copied from the WIM header, offset +0x18).  */
110         u8 guid[16];
111 } _packed_attribute;
112
113 /*
114  * Format of file: "\System Volume Information\WimOverlay.dat"
115  *
116  * Not documented by Microsoft.
117  *
118  * The file consists of a 'struct WimOverlay_dat_header' followed by one or more
119  * 'struct WimOverlay_dat_entry_1', followed by the same number of 'struct
120  * WimOverlay_dat_entry_2'.  Note that 'struct WimOverlay_dat_entry_1' is of
121  * fixed length, whereas 'struct WimOverlay_dat_entry_2' is of variable length.
122  */
123 struct WimOverlay_dat_header {
124         /* Set to WIMOVERLAY_DAT_MAGIC  */
125         le32 magic;
126 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
127
128         /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION)  */
129         le32 wim_provider_version;
130
131         /* Set to 0x00000028  */
132         le32 unknown_0x08;
133
134         /* Set to number of WIMs registered;
135          * also the number of 'struct WimOverlay_dat_entry_1' that follow.  */
136         le32 num_entries_1;
137
138         /* Set to number of WIMs registered;
139          * also the number of 'struct WimOverlay_dat_entry_2' that follow.  */
140         le32 num_entries_2;
141
142         /* Set to 0  */
143         le32 unknown_0x14;
144
145         struct WimOverlay_dat_entry_1 entry_1s[];
146 } _packed_attribute;
147
148 /* Location information about a WIM data source  */
149 struct WimOverlay_dat_entry_2 {
150         /* Set to 0  */
151         le32 unknown_0x00;
152
153         /* Set to 0  */
154         le32 unknown_0x04;
155
156         /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
157          * wim_file_name and its null terminator.  */
158         le32 entry_2_length;
159
160         /* Set to 0  */
161         le32 unknown_0x0C;
162
163         /* Set to 5  */
164         le32 unknown_0x10;
165
166         struct {
167                 /* Set to 1  */
168                 le32 unknown_0x14;
169
170                 /* Size of this inner structure, in bytes.  */
171                 le32 inner_struct_size;
172
173                 /* Set to 5  */
174                 le32 unknown_0x1C;
175
176                 /* Set to 6  */
177                 le32 unknown_0x20;
178
179                 /* Set to 0  */
180                 le32 unknown_0x24;
181
182                 /* Set to 0x48  */
183                 le32 unknown_0x28;
184
185                 /* Set to 0  */
186                 le32 unknown_0x2C;
187
188                 /*************************
189                  * Partition information
190                  ************************/
191
192                 /* Partition identifier  */
193                 union {
194                         /* (For MBR-formatted disks)  */
195                         struct {
196                                 /* Offset, in bytes, of the MBR partition, from
197                                  * the beginning of the disk.  */
198                                 le64 part_start_offset;
199
200                                 /* Set to 0  */
201                                 le64 padding;
202                         } mbr;
203
204                         /* (For GPT-formatted disks)  */
205                         struct {
206                                 /* Unique GUID of the GPT partition  */
207                                 u8 part_unique_guid[16];
208                         } gpt;
209                 } partition;
210
211                 /* Set to 0  */
212                 le32 unknown_0x40;
213
214                 /***********************
215                  * Disk information
216                  **********************/
217
218                 /* 1 for MBR, 0 for GPT  */
219                 le32 partition_table_type;
220         #define WIMOVERLAY_PARTITION_TYPE_MBR 1
221         #define WIMOVERLAY_PARTITION_TYPE_GPT 0
222
223                 /* Disk identifier  */
224                 union {
225                         /* (For MBR-formatted disks)  */
226                         struct {
227                                 /* 4-byte ID of the MBR disk  */
228                                 le32 disk_id;
229
230                                 /* Set to 0  */
231                                 le32 padding[3];
232                         } mbr;
233
234                         /* (For GPT-formatted disks)  */
235                         struct {
236                                 /* GUID of the GPT disk  */
237                                 u8 disk_guid[16];
238                         } gpt;
239                 } disk;
240
241                 /* Set to 0.  (This is the right size for some sort of optional
242                  * GUID...)  */
243                 le32 unknown_0x58[4];
244
245                 /**************************
246                  * Location in filesystem
247                  *************************/
248
249                 /* Null-terminated path to WIM file.  Begins with \ but does
250                  * *not* include drive letter!  */
251                 utf16lechar wim_file_name[];
252         } _packed_attribute;
253 } _packed_attribute;
254
255 static inline void
256 wof_check_structs(void)
257 {
258         BUILD_BUG_ON(sizeof(struct WimOverlay_dat_header) != 24);
259         BUILD_BUG_ON(sizeof(struct WimOverlay_dat_entry_1) != 40);
260         BUILD_BUG_ON(sizeof(struct WimOverlay_dat_entry_2) != 104);
261 }
262
263 /*****************************************************************************
264  *
265  * --- FSCTL_SET_EXTERNAL_BACKING ---
266  *
267  * Sets the backing source of a file.
268  *
269  * DeviceType:  9 (FILE_DEVICE_FILE_SYSTEM)
270  * Access:      0 (FILE_ANY_ACCESS)
271  * Function:    195
272  * Method:      0 (METHOD_BUFFERED)
273  *
274  * Input buffer:  'struct wof_external_info' followed by provider-specific data
275  * ('struct wim_provider_external_info' in the case of WIM).
276  *
277  * Output buffer: None
278  */
279 #define FSCTL_SET_EXTERNAL_BACKING 0x9030C
280
281 struct wim_provider_external_info {
282
283         /* Set to WIM_PROVIDER_CURRENT_VERSION.  */
284         u32 version;
285
286         /* 0 when WIM provider active, otherwise
287          * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
288          * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED.  */
289         u32 flags;
290
291         /* Integer ID that identifies the WIM.  Get this with the
292          * FSCTL_ADD_OVERLAY ioctl.  */
293         u64 data_source_id;
294
295         /* SHA1 message digest of the file's unnamed data stream.  */
296         u8 resource_hash[20];
297 };
298
299 /*****************************************************************************
300  *
301  * --- FSCTL_GET_EXTERNAL_BACKING ---
302  *
303  * Get external backing information for the specified file.
304  *
305  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
306  * Access:     0 (FILE_ANY_ACCESS)
307  * Function:   196
308  * Method:     0 (METHOD_BUFFERED)
309  *
310  * Input buffer: None
311  * Output buffer:  'struct wof_external_info' followed by provider-specific data
312  * ('struct wim_provider_external_info' in the case of WIM).
313  */
314 #define FSCTL_GET_EXTERNAL_BACKING 0x90310
315
316 /*****************************************************************************
317  *
318  * --- FSCTL_DELETE_EXTERNAL_BACKING ---
319  *
320  * Copy a file from its backing source to its volume, then disassociate it from
321  * its backing provider.
322  *
323  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
324  * Access:     0 (FILE_ANY_ACCESS)
325  * Function:   197
326  * Method:     0 (METHOD_BUFFERED)
327  *
328  * Input buffer: None
329  * Output buffer: None
330  */
331 #define FSCTL_DELETE_EXTERNAL_BACKING 0x90314
332
333 /*****************************************************************************
334  *
335  * --- FSCTL_ENUM_EXTERNAL_BACKING ---
336  *
337  * Enumerate externally backed files on a volume.
338  *
339  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
340  * Access:     0 (FILE_ANY_ACCESS)
341  * Function:   198
342  * Method:     0 (METHOD_BUFFERED)
343  *
344  * Input buffer: None
345  * Output buffer: A 16-byte buffer that receives the 128-bit file ID for the
346  * next externally backed file.
347  *
348  * The handle used may be either the volume handle or the handle for any file or
349  * directory on the volume.
350  *
351  * When all externally backed files on the volume have been enumerated, the
352  * function fails with ERROR_NO_MORE_FILES.
353  */
354 #define FSCTL_ENUM_EXTERNAL_BACKING 0x90318
355
356 /*****************************************************************************
357  *
358  * --- FSCTL_ENUM_OVERLAY ---
359  *
360  * Enumerates the volume's overlay sources from the specified provider.
361  *
362  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
363  * Access:     0 (FILE_ANY_ACCESS)
364  * Function:   199
365  * Method:     3 (METHOD_NEITHER)
366  *
367  * Input buffer:  'struct wof_external_info' to specify the provider for which
368  * to enumerate the overlay sources.
369  *
370  * Output buffer:  Provider-specific data.  For the WIM provider, an array of
371  * 'struct wim_provider_overlay_entry'.
372  *
373  * This ioctl must be performed on the volume handle, such as \\.\C:
374  */
375 #define FSCTL_ENUM_OVERLAY 0x9031F
376
377 struct wim_provider_overlay_entry {
378         /* Byte offset of the next entry from the beginning of this structure,
379          * or 0 if there are no more entries.  */
380         uint32_t next_entry_offset;
381
382         uint32_t padding;
383
384         /* Identifier for the WIM file.  */
385         uint64_t data_source_id;
386
387         /* GUID of the WIM file.  */
388         uint8_t guid[16];
389
390         /* Byte offset of the WIM's file name from the beginning of this
391          * structure.  */
392         uint32_t wim_file_name_offset;
393
394         /* Type of WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM.  */
395         uint32_t wim_type;
396
397         /* Index of the backing image in the WIM??? (This doesn't really make
398          * sense, since WIM files combine streams for all images into a single
399          * table.)  */
400         uint32_t wim_index;
401
402         /* 0 when WIM provider active, otherwise
403          * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
404          * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED.  */
405         uint32_t flags;
406
407         /* Full path to the WIM in the NT device namespace, e.g.
408          * "\Device\HardDiskVolume2\test.wim".  Seems to be null-terminated,
409          * although you probably shouldn't assume so.  */
410         wchar_t wim_file_name[];
411 };
412
413
414 /*****************************************************************************
415  *
416  * --- FSCTL_ADD_OVERLAY ---
417  *
418  * Adds a new external backing source to a volume.
419  *
420  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
421  * Access:     2 (FILE_WRITE_ACCESS)
422  * Function:   204
423  * Method:     0 (METHOD_BUFFERED)
424  *
425  * Input buffer:  'struct wof_external_info' followed by provider-specific data
426  * ('struct wim_provider_add_overlay_input' in the case of WIM).
427  *
428  * Output buffer:  Buffer large enough to receive any information resulting from
429  * the add operation.  For the WIM provider, this must be an 8 byte buffer that
430  * receives the 64-bit WIM file ID.
431  *
432  * This ioctl must be performed on the volume handle, such as \\.\C:
433  */
434 #define FSCTL_ADD_OVERLAY 0x98330
435
436 struct wim_provider_add_overlay_input {
437
438         /* Type of WIM file.  */
439         u32 wim_type;
440 #define WIM_BOOT_OS_WIM         0
441 #define WIM_BOOT_NOT_OS_WIM     1
442
443         /* Index of the image in the WIM to use??? (This doesn't really make
444          * sense, since WIM files combine streams for all images into a single
445          * table.  Set to 1 if unsure...)  */
446         u32 wim_index;
447
448         /* Byte offset of wim_file_name in this buffer, not including the
449          * preceding 'struct wof_external_info' (should be 16).  */
450         u32 wim_file_name_offset;
451
452         /* Number of bytes in wim_file_name.  */
453         u32 wim_file_name_length;
454
455         /* Full path to the WIM, e.g. "\??\C:\test-wimboot.wim".
456          * Does NOT need to be null terminated (MS docs claim otherwise).  */
457         wchar_t wim_file_name[];
458 };
459
460 /*****************************************************************************
461  *
462  * --- FSCTL_REMOVE_OVERLAY ---
463  *
464  * Removes an external backing source from a volume.
465  *
466  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
467  * Access:     2 (FILE_WRITE_ACCESS)
468  * Function:   205
469  * Method:     0 (METHOD_BUFFERED)
470  *
471  * Input buffer:  'struct wof_external_info' followed by provider-specific data
472  * ('struct wim_provider_remove_overlay_input' in the case of WIM).
473  *
474  * Output buffer:  None
475  *
476  * This ioctl must be performed on the volume handle, such as \\.\C:
477  */
478 #define FSCTL_REMOVE_OVERLAY 0x98334
479
480 struct wim_provider_remove_overlay_input {
481         /* Integer ID that identifies the WIM.  */
482         u64 data_source_id;
483 };
484
485
486 /*****************************************************************************
487  *
488  * --- FSCTL_UPDATE_OVERLAY ---
489  *
490  * Updates an overlay source for a volume.
491  *
492  * DeviceType: 9 (FILE_DEVICE_FILE_SYSTEM)
493  * Access:     2 (FILE_WRITE_ACCESS)
494  * Function:   206
495  * Method:     0 (METHOD_BUFFERED)
496  *
497  * Input buffer:  'struct wof_external_info' followed by provider-specific data
498  * ('struct wim_provider_update_overlay_input' in the case of WIM).
499  *
500  * Output buffer:  None
501  *
502  * This ioctl must be performed on the volume handle, such as \\.\C:
503  */
504 #define FSCTL_UPDATE_OVERLAY 0x98338
505
506 struct wim_provider_update_overlay_input {
507         /* Integer ID that identifies the WIM data source.  */
508         u64 data_source_id;
509
510         /* Byte offset of wim_file_name in this buffer, not including the
511          * preceding 'struct wof_external_info' (should be 16).  */
512         u32 wim_file_name_offset;
513
514         /* Number of bytes in wim_file_name.  */
515         u32 wim_file_name_length;
516
517         /* Full path to the WIM, e.g. "\??\C:\test-wimboot.wim".
518          * Does NOT need to be null terminated (MS docs claim otherwise).
519          * This WIM must be renamed from the original WIM, or at least be an
520          * identical copy of it!  (Maybe the WIM's GUID field is checked.)  */
521         wchar_t wim_file_name[];
522 };
523
524 #endif /* _WOF_H_ */