]> wimlib.net Git - wimlib/blobdiff - include/wimlib/reparse.h
Add randomized testing program
[wimlib] / include / wimlib / reparse.h
index 04974a1280415f7fdd64694a77d17720f0b46684..dce19a22130087ec1cc9475a88b060aab513dbdb 100644 (file)
 #ifndef _WIMLIB_REPARSE_H
 #define _WIMLIB_REPARSE_H
 
+#include "wimlib/inode.h" /* for reparse tag definitions */
 #include "wimlib/types.h"
 
-struct wim_inode;
-struct wim_lookup_table;
+struct blob_descriptor;
+struct blob_table;
+
+/* Windows enforces this limit on the size of a reparse point buffer.  */
+#define REPARSE_POINT_MAX_SIZE 16384
+
+/*
+ * On-disk format of a reparse point buffer.  See:
+ *     https://msdn.microsoft.com/en-us/library/dd541671.aspx
+ *
+ * Note: we are not using _packed_attribute for this structure, so only cast to
+ * this if properly aligned!
+ */
+struct reparse_buffer_disk {
+       le32 rptag;
+       le16 rpdatalen;
+       le16 rpreserved;
+       union {
+               u8 rpdata[REPARSE_POINT_MAX_SIZE - 8];
+
+               struct {
+                       le16 substitute_name_offset;
+                       le16 substitute_name_nbytes;
+                       le16 print_name_offset;
+                       le16 print_name_nbytes;
+
+                       union {
+                               struct {
+                                       u8 data[REPARSE_POINT_MAX_SIZE - 16];
+                               } junction;
+
+                               struct {
+                                       le32 flags;
+                       #define SYMBOLIC_LINK_RELATIVE 0x00000001
+                                       u8 data[REPARSE_POINT_MAX_SIZE - 20];
+                               } symlink;
+                       };
+               } link;
+       };
+};
 
-#define REPARSE_POINT_MAX_SIZE (16 * 1024)
+#define REPARSE_DATA_OFFSET ((unsigned)offsetof(struct reparse_buffer_disk, rpdata))
 
-/* Structured format for symbolic link, junction point, or mount point reparse
- * data. */
-struct reparse_data {
-       /* Reparse point tag (see WIM_IO_REPARSE_TAG_* values) */
-       u32 rptag;
+#define REPARSE_DATA_MAX_SIZE (REPARSE_POINT_MAX_SIZE - REPARSE_DATA_OFFSET)
+
+static _unused_attribute void
+check_reparse_buffer_disk(void)
+{
+       STATIC_ASSERT(offsetof(struct reparse_buffer_disk, rpdata) == 8);
+       STATIC_ASSERT(offsetof(struct reparse_buffer_disk, link.junction.data) == 16);
+       STATIC_ASSERT(offsetof(struct reparse_buffer_disk, link.symlink.data) == 20);
+       STATIC_ASSERT(sizeof(struct reparse_buffer_disk) == REPARSE_POINT_MAX_SIZE);
+}
 
-       /* Length of reparse data, not including the 8-byte header (ReparseTag,
       * ReparseDataLength, ReparseReserved) */
-       u16 rpdatalen;
+/* Wrapper around a symbolic link or junction reparse point
* (WIM_IO_REPARSE_TAG_SYMLINK or WIM_IO_REPARSE_TAG_MOUNT_POINT)  */
+struct link_reparse_point {
 
-       /* ReparseReserved */
+       u32 rptag;
        u16 rpreserved;
 
-       /* Flags (only for WIM_IO_REPARSE_TAG_SYMLINK reparse points).
-        * SYMBOLIC_LINK_RELATIVE means this is a relative symbolic link;
-        * otherwise should be set to 0. */
-#define SYMBOLIC_LINK_RELATIVE 0x00000001
-       u32 rpflags;
+       /* Flags, valid for symbolic links only  */
+       u32 symlink_flags;
 
-       /* Pointer to the substitute name of the link (UTF-16LE). */
+       /* Pointers to the substitute name and print name of the link,
+        * potentially not null terminated  */
        utf16lechar *substitute_name;
-
-       /* Pointer to the print name of the link (UTF-16LE). */
        utf16lechar *print_name;
 
-       /* Number of bytes of the substitute name, not including null terminator
-        * if present */
-       u16 substitute_name_nbytes;
-
-       /* Number of bytes of the print name, not including null terminator if
-        * present */
-       u16 print_name_nbytes;
+       /* Lengths of the substitute and print names in bytes, not including
+        * their null terminators if present  */
+       size_t substitute_name_nbytes;
+       size_t print_name_nbytes;
 };
 
-enum {
-       SUBST_NAME_IS_RELATIVE_LINK = -1,
-       SUBST_NAME_IS_VOLUME_JUNCTION = -2,
-       SUBST_NAME_IS_UNKNOWN = -3,
-};
-extern int
-parse_substitute_name(const utf16lechar *substitute_name,
-                     u16 substitute_name_nbytes,
-                     u32 rptag);
+static inline bool
+link_is_relative_symlink(const struct link_reparse_point *link)
+{
+       return link->rptag == WIM_IO_REPARSE_TAG_SYMLINK &&
+              (link->symlink_flags & SYMBOLIC_LINK_RELATIVE);
+}
 
-extern int
-parse_reparse_data(const u8 * restrict rpbuf, u16 rpbuflen,
-                  struct reparse_data * restrict rpdata);
+extern void
+complete_reparse_point(struct reparse_buffer_disk *rpbuf,
+                      const struct wim_inode *inode, u16 blob_size);
 
 extern int
-make_reparse_buffer(const struct reparse_data * restrict rpdata,
-                   u8 * restrict rpbuf,
-                   u16 * restrict rpbuflen_ret);
+parse_link_reparse_point(const struct reparse_buffer_disk *rpbuf, u16 rpbuflen,
+                        struct link_reparse_point *link);
 
 extern int
-wim_inode_get_reparse_data(const struct wim_inode * restrict inode,
-                          u8 * restrict rpbuf,
-                          u16 * restrict rpbuflen_ret,
-                          struct wim_lookup_table_entry *lte_override);
+make_link_reparse_point(const struct link_reparse_point *link,
+                       struct reparse_buffer_disk *rpbuf, u16 *rpbuflen_ret);
 
 #ifndef __WIN32__
-ssize_t
-wim_inode_readlink(const struct wim_inode * restrict inode, char * restrict buf,
-                  size_t buf_len, struct wim_lookup_table_entry *lte);
+extern int
+wim_inode_readlink(const struct wim_inode *inode, char *buf, size_t bufsize,
+                  const struct blob_descriptor *blob,
+                  const char *altroot, size_t altroot_len);
 
 extern int
 wim_inode_set_symlink(struct wim_inode *inode, const char *target,
-                     struct wim_lookup_table *lookup_table);
+                     struct blob_table *blob_table);
 #endif
 
 #endif /* _WIMLIB_REPARSE_H */