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