Use WIM_LINK_TYPE_NONE as default, as documented
[wimlib] / src / wim.c
index f7d9eaccf38107277466d04cc97693a72007c5dd..99a8c70072e89c1f1a6b563bc88ba229f09ed7cf 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -1,24 +1,27 @@
 /*
  * wim.c
- *
- *
+ */
+
+/*
  * Copyright (C) 2010 Carl Thijssen
  * Copyright (C) 2012 Eric Biggers
  *
  * wimlib - Library for working with WIM files 
  *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 2.1 of the License, or (at your option) any
- * later version.
+ * This file is part of wimlib, a library for working with WIM files.
+ *
+ * wimlib is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
  *
- * This library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
  *
- * You should have received a copy of the GNU Lesser General Public License along
- * with this library; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
 #include "wimlib_internal.h"
@@ -29,7 +32,7 @@
 
 static int print_metadata(WIMStruct *w)
 {
-#if 0
+#ifdef ENABLE_SECURITY_DATA
        print_security_data(wim_security_data(w));
 #endif
        return for_dentry_in_tree(wim_root_dentry(w), print_dentry, 
@@ -43,15 +46,15 @@ static int print_files(WIMStruct *w)
                                  NULL);
 }
 
-static WIMStruct *new_wim_struct()
+WIMStruct *new_wim_struct()
 {
        WIMStruct *w;
        
        w = CALLOC(1, sizeof(WIMStruct));
        if (!w)
                return NULL;
-       w->link_type      = WIM_LINK_TYPE_HARD;
-       w->current_image  = WIM_NO_IMAGE;
+       w->link_type     = WIM_LINK_TYPE_NONE;
+       w->current_image = WIM_NO_IMAGE;
        return w;
 }
 
@@ -63,7 +66,7 @@ static WIMStruct *new_wim_struct()
  */
 int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *))
 {
-       int ret;
+       int ret = 0;
        int i;
        int image_count;
 
@@ -220,22 +223,28 @@ int wimlib_select_image(WIMStruct *w, int image)
                DEBUG("Freeing image %u\n", w->current_image);
                imd = wim_get_current_image_metadata(w);
                free_dentry_tree(imd->root_dentry, NULL, false);
-#if 0
-               destroy_security_data(&imd->security_data);
-#endif
                imd->root_dentry = NULL;
+#ifdef ENABLE_SECURITY_DATA
+               free_security_data(imd->security_data);
+               imd->security_data = NULL;
+#endif
        }
 
        w->current_image = image;
 
-       if (wim_root_dentry(w))
+       if (wim_root_dentry(w)) {
                return 0;
-       else
+       } else {
+               #ifdef ENABLE_DEBUG
+               DEBUG("Reading metadata resource specified by the following "
+                               "lookup table entry:\n");
+               print_lookup_table_entry(wim_metadata_lookup_table_entry(w), NULL);
+               #endif
                return read_metadata_resource(w->fp, 
                                wim_metadata_resource_entry(w),
                                wimlib_get_compression_type(w), 
-                               /*wim_security_data(w), */
-                               wim_root_dentry_p(w));
+                               wim_get_current_image_metadata(w));
+       }
 }
 
 
@@ -306,7 +315,7 @@ WIMLIBAPI void wimlib_print_wim_information(const WIMStruct *w)
        printf("Image Count:    %d\n", hdr->image_count);
        printf("Compression:    %s\n", wimlib_get_compression_type_string(
                                                wimlib_get_compression_type(w)));
-       printf("Part Number:    %d/%d\n", 1, 1);
+       printf("Part Number:    %d/%d\n", hdr->part_number, hdr->total_parts);
        printf("Boot Index:     %d\n", hdr->boot_idx);
        printf("Size:           %"PRIu64" bytes\n", 
                                wim_info_get_total_bytes(w->wim_info));
@@ -369,6 +378,14 @@ WIMLIBAPI int wimlib_set_boot_idx(WIMStruct *w, int boot_idx)
        return 0;
 }
 
+WIMLIBAPI int wimlib_get_part_number(const WIMStruct *w, int *total_parts_ret)
+{
+       if (total_parts_ret)
+               *total_parts_ret = w->hdr.total_parts;
+       return w->hdr.part_number;
+}
+                                   
+
 WIMLIBAPI int wimlib_get_boot_idx(const WIMStruct *w)
 {
        return w->hdr.boot_idx;
@@ -378,7 +395,7 @@ WIMLIBAPI int wimlib_get_boot_idx(const WIMStruct *w)
  * Begins the reading of a WIM file; opens the file and reads its header and
  * lookup table, and optionally checks the integrity.
  */
-static int wim_begin_read(WIMStruct *w, const char *in_wim_path, int flags)
+static int begin_read(WIMStruct *w, const char *in_wim_path, int flags)
 {
        int ret;
        uint xml_num_images;
@@ -401,7 +418,7 @@ static int wim_begin_read(WIMStruct *w, const char *in_wim_path, int flags)
                goto done;
        }
 
-       ret = read_header(w->fp, &w->hdr);
+       ret = read_header(w->fp, &w->hdr, flags & WIMLIB_OPEN_FLAG_SPLIT_OK);
        if (ret != 0)
                goto done;
 
@@ -409,10 +426,9 @@ static int wim_begin_read(WIMStruct *w, const char *in_wim_path, int flags)
 
        /* If the boot index is invalid, print a warning and set it to 0 */
        if (w->hdr.boot_idx > w->hdr.image_count) {
-               ERROR("WARNING:  In `%s', image %u is marked as bootable,\n",
-                               in_wim_path, w->hdr.boot_idx);
-               ERROR("    but there are only %u images!\n", 
-                               w->hdr.image_count);
+               WARNING("In `%s', image %u is marked as bootable,\n"
+                       "\tbut there are only %u images!\n",
+                        in_wim_path, w->hdr.boot_idx, w->hdr.image_count);
                w->hdr.boot_idx = 0;
        }
 
@@ -433,8 +449,8 @@ static int wim_begin_read(WIMStruct *w, const char *in_wim_path, int flags)
                        goto done;
                }
                if (integrity_status == WIM_INTEGRITY_NONEXISTENT) {
-                       DEBUG("WARNING: No integrity information; skipping "
-                                       "integrity check.\n");
+                       WARNING("No integrity information for `%s'; skipping "
+                                       "integrity check.\n", w->filename);
                } else if (integrity_status == WIM_INTEGRITY_NOT_OK) {
                        ERROR("WIM is not intact! (Failed integrity check)\n");
                        ret = WIMLIB_ERR_INTEGRITY;
@@ -472,27 +488,28 @@ static int wim_begin_read(WIMStruct *w, const char *in_wim_path, int flags)
        ret = for_lookup_table_entry(w->lookup_table, 
                                     append_metadata_resource_entry, w);
 
-       if (ret != 0)
+       if (ret != 0 && w->hdr.part_number == 1)
                goto done;
 
        /* Make sure all the expected images were found.  (We already have
         * returned false if *extra* images were found) */
-       if (w->current_image != w->hdr.image_count) {
+       if (w->current_image != w->hdr.image_count && w->hdr.part_number == 1) {
                ERROR("Only found %u images in WIM, but expected %u!\n",
                                w->current_image, w->hdr.image_count);
                ret = WIMLIB_ERR_IMAGE_COUNT;
                goto done;
        }
 
-       w->current_image = WIM_NO_IMAGE;
 
        /* Sort images by the position of their metadata resources.  I'm
         * assuming that is what determines the other of the images in the WIM
         * file, rather than their order in the lookup table, which may be
         * random because of hashing. */
-       qsort(w->image_metadata, w->hdr.image_count, 
+       qsort(w->image_metadata, w->current_image,
              sizeof(struct image_metadata), sort_image_metadata_by_position);
 
+       w->current_image = WIM_NO_IMAGE;
+
        /* Read the XML data. */
        ret = read_xml_data(w->fp, &w->hdr.xml_res_entry, 
                            &w->xml_data, &w->wim_info);
@@ -535,7 +552,7 @@ WIMLIBAPI int wimlib_open_wim(const char *wim_file, int flags,
        if (!w)
                return WIMLIB_ERR_NOMEM;
 
-       ret = wim_begin_read(w, wim_file, flags);
+       ret = begin_read(w, wim_file, flags);
        if (ret != 0) {
                ERROR("Could not begin reading the WIM file `%s'\n", wim_file);
                FREE(w);
@@ -545,15 +562,6 @@ WIMLIBAPI int wimlib_open_wim(const char *wim_file, int flags,
        return 0;
 }
 
-/**
- * Frees internal memory allocated by WIMLIB for a WIM file, and closes it if it
- * is still open.
- */
-void wimlib_destroy(WIMStruct *w)
-{
-
-}
-
 /* Frees the memory for the WIMStruct, including all internal memory; also
  * closes all files associated with the WIMStruct.  */
 WIMLIBAPI void wimlib_free(WIMStruct *w)
@@ -574,9 +582,13 @@ WIMLIBAPI void wimlib_free(WIMStruct *w)
        FREE(w->xml_data);
        free_wim_info(w->wim_info);
        if (w->image_metadata) {
-               for (i = 0; i < w->hdr.image_count; i++)
+               for (i = 0; i < w->hdr.image_count; i++) {
                        free_dentry_tree(w->image_metadata[i].root_dentry, 
                                         NULL, false);
+                       #ifdef ENABLE_SECURITY_DATA
+                       free_security_data(w->image_metadata[i].security_data);
+                       #endif
+               }
                FREE(w->image_metadata);
        }
        FREE(w);