]> wimlib.net Git - wimlib/blobdiff - src/wimboot.c
mount_image.c: add fallback definitions of RENAME_* constants
[wimlib] / src / wimboot.c
index 16ea1c6da0ebaba7f639b3b728876562291b1068..115a56996e39759832ae62b3265f9a2bacfee725 100644 (file)
@@ -3,15 +3,15 @@
  *
  * Support for creating WIMBoot pointer files.
  *
- * See http://technet.microsoft.com/en-us/library/dn594399.aspx for general
- * information about WIMBoot.
+ * For general information about WIMBoot, see
+ * https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-8.1-and-8/dn594399(v=win.10)
  *
  * Note that WIMBoot pointer files are actually implemented on top of the
  * Windows Overlay Filesystem filter (WOF).  See wof.h for more info.
  */
 
 /*
- * Copyright (C) 2014-2016 Eric Biggers
+ * Copyright (C) 2014-2021 Eric Biggers
  *
  * This file 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
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with this file; if not, see http://www.gnu.org/licenses/.
+ * along with this file; if not, see https://www.gnu.org/licenses/.
  */
 
-#ifdef __WIN32__
+#ifdef _WIN32
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
@@ -511,6 +511,21 @@ prepare_wimoverlay_dat(const struct WimOverlay_dat_header *old_hdr,
        return 0;
 }
 
+static bool
+valid_wim_filename(const struct WimOverlay_dat_entry_2 *entry, size_t name_len)
+{
+       size_t i;
+
+       if (name_len % sizeof(wchar_t))
+               return false;
+       name_len /= sizeof(wchar_t);
+       if (name_len < 2)
+               return false;
+       for (i = 0; i < name_len && entry->wim_file_name[i] != 0; i++)
+               ;
+       return i == name_len - 1;
+}
+
 /*
  * Reads and validates a WimOverlay.dat file.
  *
@@ -686,13 +701,7 @@ retry:
 
                wim_file_name_length = entry_1->entry_2_length -
                                        sizeof(struct WimOverlay_dat_entry_2);
-               if ((wim_file_name_length < 2 * sizeof(wchar_t)) ||
-                   (wim_file_name_length % sizeof(wchar_t) != 0) ||
-                   (wmemchr(entry_2->wim_file_name, L'\0',
-                            wim_file_name_length / sizeof(wchar_t))
-                    != &entry_2->wim_file_name[wim_file_name_length /
-                                               sizeof(wchar_t) - 1]))
-               {
+               if (!valid_wim_filename(entry_2, wim_file_name_length)) {
                        ERROR("\"%ls\": entry %"PRIu32" (2) "
                              "(data source ID 0x%016"PRIx64") "
                              "has invalid WIM file name",
@@ -878,8 +887,9 @@ wimboot_alloc_data_source_id(const wchar_t *wim_path,
        size_t wim_file_name_length;
        void *in;
        size_t insize;
-       struct wof_external_info *wof_info;
-       struct wim_provider_add_overlay_input *wim_info;
+       WOF_EXTERNAL_INFO *wof_info;
+       WIM_PROVIDER_ADD_OVERLAY_INPUT *wim_info;
+       wchar_t *WimFileName;
        HANDLE h;
        u64 data_source_id;
        DWORD bytes_returned;
@@ -899,28 +909,25 @@ wimboot_alloc_data_source_id(const wchar_t *wim_path,
        wim_file_name_length = sizeof(wchar_t) *
                               (wim_path_nchars + prefix_nchars);
 
-       insize = sizeof(struct wof_external_info) +
-                sizeof(struct wim_provider_add_overlay_input) +
-                wim_file_name_length;
-
-       in = MALLOC(insize);
+       insize = sizeof(*wof_info) + sizeof(*wim_info) + wim_file_name_length;
+       in = CALLOC(1, insize);
        if (!in) {
                ret = WIMLIB_ERR_NOMEM;
                goto out;
        }
 
-       wof_info = (struct wof_external_info *)in;
-       wof_info->version = WOF_CURRENT_VERSION;
-       wof_info->provider = WOF_PROVIDER_WIM;
+       wof_info = (WOF_EXTERNAL_INFO *)in;
+       wof_info->Version = WOF_CURRENT_VERSION;
+       wof_info->Provider = WOF_PROVIDER_WIM;
 
-       wim_info = (struct wim_provider_add_overlay_input *)(wof_info + 1);
-       wim_info->wim_type = WIM_BOOT_NOT_OS_WIM;
-       wim_info->wim_index = image;
-       wim_info->wim_file_name_offset = offsetof(struct wim_provider_add_overlay_input,
-                                                 wim_file_name);
-       wim_info->wim_file_name_length = wim_file_name_length;
-       wmemcpy(&wim_info->wim_file_name[0], prefix, prefix_nchars);
-       wmemcpy(&wim_info->wim_file_name[prefix_nchars], wim_path, wim_path_nchars);
+       wim_info = (WIM_PROVIDER_ADD_OVERLAY_INPUT *)(wof_info + 1);
+       wim_info->WimType = WIM_BOOT_NOT_OS_WIM;
+       wim_info->WimIndex = image;
+       wim_info->WimFileNameOffset = sizeof(*wim_info);
+       wim_info->WimFileNameLength = wim_file_name_length;
+       WimFileName = (wchar_t *)(wim_info + 1);
+       wmemcpy(WimFileName, prefix, prefix_nchars);
+       wmemcpy(&WimFileName[prefix_nchars], wim_path, wim_path_nchars);
 
 retry_ioctl:
        h = open_file(drive_path, GENERIC_WRITE);
@@ -1018,20 +1025,20 @@ wimboot_set_pointer(HANDLE h,
                 * using FSCTL_SET_EXTERNAL_BACKING.  */
                unsigned int max_retries = 4;
                struct {
-                       struct wof_external_info wof_info;
-                       struct wim_provider_external_info wim_info;
+                       WOF_EXTERNAL_INFO wof_info;
+                       WIM_PROVIDER_EXTERNAL_INFO wim_info;
                } in;
 
        retry:
                memset(&in, 0, sizeof(in));
 
-               in.wof_info.version = WOF_CURRENT_VERSION;
-               in.wof_info.provider = WOF_PROVIDER_WIM;
+               in.wof_info.Version = WOF_CURRENT_VERSION;
+               in.wof_info.Provider = WOF_PROVIDER_WIM;
 
-               in.wim_info.version = WIM_PROVIDER_CURRENT_VERSION;
-               in.wim_info.flags = 0;
-               in.wim_info.data_source_id = data_source_id;
-               copy_hash(in.wim_info.unnamed_data_stream_hash, blob->hash);
+               in.wim_info.Version = WIM_PROVIDER_CURRENT_VERSION;
+               in.wim_info.Flags = 0;
+               in.wim_info.DataSourceId.QuadPart = data_source_id;
+               copy_hash(in.wim_info.ResourceHash, blob->hash);
 
                /* blob_table_hash is not necessary  */
 
@@ -1065,20 +1072,20 @@ wimboot_set_pointer(HANDLE h,
                                le16 rpdatalen;
                                le16 rpreserved;
                        } hdr;
-                       struct wof_external_info wof_info;
+                       WOF_EXTERNAL_INFO wof_info;
                        struct wim_provider_rpdata wim_info;
                } in;
 
                STATIC_ASSERT(sizeof(in) == 8 +
-                             sizeof(struct wof_external_info) +
+                             sizeof(WOF_EXTERNAL_INFO) +
                              sizeof(struct wim_provider_rpdata));
 
                in.hdr.rptag = WIM_IO_REPARSE_TAG_WOF;
                in.hdr.rpdatalen = sizeof(in) - sizeof(in.hdr);
                in.hdr.rpreserved = 0;
 
-               in.wof_info.version = WOF_CURRENT_VERSION;
-               in.wof_info.provider = WOF_PROVIDER_WIM;
+               in.wof_info.Version = WOF_CURRENT_VERSION;
+               in.wof_info.Provider = WOF_PROVIDER_WIM;
 
                in.wim_info.version = 2;
                in.wim_info.flags = 0;
@@ -1113,4 +1120,4 @@ wimboot_set_pointer(HANDLE h,
        return true;
 }
 
-#endif /* __WIN32__ */
+#endif /* _WIN32 */