]> wimlib.net Git - wimlib/blobdiff - src/extract.c
add System Compression support
[wimlib] / src / extract.c
index 6b35a90367d0b106a9a0152804481c47c27c24e1..e80bbe94a4d2e65f0b23cc0b8ce4ee96c94d53fb 100644 (file)
         WIMLIB_EXTRACT_FLAG_STRICT_GLOB                |       \
         WIMLIB_EXTRACT_FLAG_NO_ATTRIBUTES              |       \
         WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE  |       \
-        WIMLIB_EXTRACT_FLAG_WIMBOOT)
+        WIMLIB_EXTRACT_FLAG_WIMBOOT                    |       \
+        WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS4K           |       \
+        WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS8K           |       \
+        WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS16K          |       \
+        WIMLIB_EXTRACT_FLAG_COMPACT_LZX                        \
+        )
 
 /* Send WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE or
  * WIMLIB_PROGRESS_MSG_EXTRACT_METADATA.  */
@@ -655,19 +660,20 @@ file_name_valid(utf16lechar *name, size_t num_chars, bool fix)
        if (num_chars == 0)
                return true;
        for (i = 0; i < num_chars; i++) {
-               switch (name[i]) {
+               switch (le16_to_cpu(name[i])) {
        #ifdef __WIN32__
-               case cpu_to_le16('\\'):
-               case cpu_to_le16(':'):
-               case cpu_to_le16('*'):
-               case cpu_to_le16('?'):
-               case cpu_to_le16('"'):
-               case cpu_to_le16('<'):
-               case cpu_to_le16('>'):
-               case cpu_to_le16('|'):
+               case '\x01'...'\x1F':
+               case '\\':
+               case ':':
+               case '*':
+               case '?':
+               case '"':
+               case '<':
+               case '>':
+               case '|':
        #endif
-               case cpu_to_le16('/'):
-               case cpu_to_le16('\0'):
+               case '/':
+               case '\0':
                        if (fix)
                                name[i] = replacement_char;
                        else
@@ -675,16 +681,6 @@ file_name_valid(utf16lechar *name, size_t num_chars, bool fix)
                }
        }
 
-#ifdef __WIN32__
-       if (name[num_chars - 1] == cpu_to_le16(' ') ||
-           name[num_chars - 1] == cpu_to_le16('.'))
-       {
-               if (fix)
-                       name[num_chars - 1] = replacement_char;
-               else
-                       return false;
-       }
-#endif
        return true;
 }
 
@@ -982,10 +978,11 @@ ref_stream_if_needed(struct wim_dentry *dentry, struct wim_inode *inode,
                         * - file is a directory
                         * - file is encrypted
                         * - backend needs to create the file as UNIX symlink
-                        * - backend will extract the stream as externally backed
+                        * - backend will extract the stream as externally
+                        *   backed from the WIM archive itself
                         */
-                       if (ctx->apply_ops->will_externally_back) {
-                               int ret = (*ctx->apply_ops->will_externally_back)(dentry, ctx);
+                       if (ctx->apply_ops->will_back_from_wim) {
+                               int ret = (*ctx->apply_ops->will_back_from_wim)(dentry, ctx);
                                if (ret > 0) /* Error?  */
                                        return ret;
                                if (ret < 0) /* Won't externally back?  */
@@ -1488,6 +1485,34 @@ check_extract_flags(const WIMStruct *wim, int *extract_flags_p)
 #endif
        }
 
+       if (extract_flags & (WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS4K |
+                            WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS8K |
+                            WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS16K |
+                            WIMLIB_EXTRACT_FLAG_COMPACT_LZX))
+       {
+       #ifdef __WIN32__
+               int count = 0;
+               count += ((extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS4K) != 0);
+               count += ((extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS8K) != 0);
+               count += ((extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS16K) != 0);
+               count += ((extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_LZX) != 0);
+               if (count != 1) {
+                       ERROR("Only one compression format can be specified "
+                             "for compact-mode extraction!");
+                       return WIMLIB_ERR_INVALID_PARAM;
+               }
+               if (extract_flags & WIMLIB_EXTRACT_FLAG_WIMBOOT) {
+                       ERROR("Compact-mode extraction and WIMBoot-mode "
+                             "extraction are mutually exclusive!");
+                       return WIMLIB_ERR_INVALID_PARAM;
+               }
+       #else
+               ERROR("Compact-mode extraction (System Compression) "
+                     "is only supported on Windows!");
+               return WIMLIB_ERR_UNSUPPORTED;
+       #endif
+       }
+
 
        if ((extract_flags & (WIMLIB_EXTRACT_FLAG_RPFIX |
                              WIMLIB_EXTRACT_FLAG_NORPFIX |