/*
* Copyright (C) 2014 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * 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
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * 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 General Public License for more
+ * This file 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 General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ * 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/.
*/
+#ifdef __WIN32__
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "wimlib/win32_common.h"
-#include "wimlib/win32.h"
+
#include "wimlib/assert.h"
+#include "wimlib/blob_table.h"
+#include "wimlib/inode.h"
#include "wimlib/error.h"
-#include "wimlib/lookup_table.h"
#include "wimlib/util.h"
#include "wimlib/wimboot.h"
+#include "wimlib/win32.h"
#include "wimlib/wof.h"
static HANDLE
*/
static int
query_partition_and_disk_info(const wchar_t *path,
- PARTITION_INFORMATION_EX *part_info_ret,
+ PARTITION_INFORMATION_EX *part_info,
DRIVE_LAYOUT_INFORMATION_EX *drive_info_ret)
{
- HANDLE h;
wchar_t vol_name[] = L"\\\\.\\X:";
wchar_t disk_name[] = L"\\\\?\\PhysicalDriveXXXXXXXXXX";
-
- PARTITION_INFORMATION_EX part_info;
- size_t extents_size = sizeof(VOLUME_DISK_EXTENTS) + 4 * sizeof(DISK_EXTENT);
- VOLUME_DISK_EXTENTS *extents = alloca(extents_size);
- size_t drive_info_size = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
- 8 * sizeof(PARTITION_INFORMATION_EX);
- DRIVE_LAYOUT_INFORMATION_EX *drive_info = alloca(drive_info_size);
+ HANDLE h = INVALID_HANDLE_VALUE;
+ VOLUME_DISK_EXTENTS *extents = NULL;
+ size_t extents_size;
+ DRIVE_LAYOUT_INFORMATION_EX *drive_info = NULL;
+ size_t drive_info_size;
+ int ret;
wimlib_assert(path[0] != L'\0' && path[1] == L':');
h = open_file(vol_name, GENERIC_READ);
if (h == INVALID_HANDLE_VALUE) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't open volume device", vol_name);
- return WIMLIB_ERR_OPEN;
+ win32_error(GetLastError(), L"\"%ls\": Can't open volume device",
+ vol_name);
+ ret = WIMLIB_ERR_OPEN;
+ goto out;
}
if (!query_device(h, IOCTL_DISK_GET_PARTITION_INFO_EX,
- &part_info, sizeof(part_info)))
+ part_info, sizeof(PARTITION_INFORMATION_EX)))
{
- ERROR("\"%ls\": Can't get partition info (err=0x%08"PRIx32")",
- vol_name, (u32)GetLastError());
- CloseHandle(h);
- return WIMLIB_ERR_READ;
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't get partition info", vol_name);
+ ret = WIMLIB_ERR_READ;
+ goto out;
}
- if (!query_device(h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
- extents, extents_size))
- {
- ERROR("\"%ls\": Can't get volume extent info (err=0x%08"PRIx32")",
- vol_name, (u32)GetLastError());
- CloseHandle(h);
- return WIMLIB_ERR_READ;
+ extents_size = sizeof(VOLUME_DISK_EXTENTS);
+ for (;;) {
+ extents_size += 4 * sizeof(DISK_EXTENT);
+ extents = MALLOC(extents_size);
+ if (!extents) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out;
+ }
+
+ if (query_device(h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
+ extents, extents_size))
+ break;
+ if (GetLastError() != ERROR_MORE_DATA) {
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't get volume extent info",
+ vol_name);
+ ret = WIMLIB_ERR_READ;
+ goto out;
+ }
+ FREE(extents);
}
CloseHandle(h);
+ h = INVALID_HANDLE_VALUE;
if (extents->NumberOfDiskExtents != 1) {
ERROR("\"%ls\": This volume has %"PRIu32" disk extents, "
"but this code is untested for more than 1",
vol_name, (u32)extents->NumberOfDiskExtents);
- return WIMLIB_ERR_UNSUPPORTED;
+ ret = WIMLIB_ERR_UNSUPPORTED;
+ goto out;
}
wsprintf(wcschr(disk_name, L'X'), L"%"PRIu32,
h = open_file(disk_name, GENERIC_READ);
if (h == INVALID_HANDLE_VALUE) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't open disk device", disk_name);
- return WIMLIB_ERR_OPEN;
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't open disk device", disk_name);
+ ret = WIMLIB_ERR_OPEN;
+ goto out;
}
- if (!query_device(h, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
- drive_info, drive_info_size))
- {
- ERROR("\"%ls\": Can't get disk info (err=0x%08"PRIx32")",
- disk_name, (u32)GetLastError());
- CloseHandle(h);
- return WIMLIB_ERR_READ;
+ drive_info_size = sizeof(DRIVE_LAYOUT_INFORMATION_EX);
+ for (;;) {
+ drive_info_size += 4 * sizeof(PARTITION_INFORMATION_EX);
+ drive_info = MALLOC(drive_info_size);
+ if (!drive_info) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out;
+ }
+
+ if (query_device(h, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
+ drive_info, drive_info_size))
+ break;
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't get disk info", disk_name);
+ ret = WIMLIB_ERR_READ;
+ goto out;
+ }
+ FREE(drive_info);
}
+ *drive_info_ret = *drive_info; /* doesn't include partitions */
CloseHandle(h);
+ h = INVALID_HANDLE_VALUE;
- if (drive_info->PartitionStyle != part_info.PartitionStyle) {
+ if (drive_info->PartitionStyle != part_info->PartitionStyle) {
ERROR("\"%ls\", \"%ls\": Inconsistent partition table type!",
vol_name, disk_name);
- return WIMLIB_ERR_UNSUPPORTED;
+ ret = WIMLIB_ERR_UNSUPPORTED;
+ goto out;
}
- if (part_info.PartitionStyle == PARTITION_STYLE_GPT) {
- BUILD_BUG_ON(sizeof(part_info.Gpt.PartitionId) !=
- sizeof(drive_info->Gpt.DiskId));
- if (!memcmp(&part_info.Gpt.PartitionId,
+ if (part_info->PartitionStyle == PARTITION_STYLE_GPT) {
+ STATIC_ASSERT(sizeof(part_info->Gpt.PartitionId) ==
+ sizeof(drive_info->Gpt.DiskId));
+ if (!memcmp(&part_info->Gpt.PartitionId,
&drive_info->Gpt.DiskId,
sizeof(drive_info->Gpt.DiskId)))
{
ERROR("\"%ls\", \"%ls\": Partition GUID is the "
"same as the disk GUID???", vol_name, disk_name);
- return WIMLIB_ERR_UNSUPPORTED;
+ ret = WIMLIB_ERR_UNSUPPORTED;
+ goto out;
}
}
- if (part_info.PartitionStyle != PARTITION_STYLE_MBR &&
- part_info.PartitionStyle != PARTITION_STYLE_GPT)
+ if (part_info->PartitionStyle != PARTITION_STYLE_MBR &&
+ part_info->PartitionStyle != PARTITION_STYLE_GPT)
{
ERROR("\"%ls\": Unknown partition style 0x%08"PRIx32,
- vol_name, (u32)part_info.PartitionStyle);
- return WIMLIB_ERR_UNSUPPORTED;
+ vol_name, (u32)part_info->PartitionStyle);
+ ret = WIMLIB_ERR_UNSUPPORTED;
+ goto out;
}
- *part_info_ret = part_info;
- *drive_info_ret = *drive_info;
- return 0;
+ ret = 0;
+out:
+ FREE(extents);
+ FREE(drive_info);
+ if (h != INVALID_HANDLE_VALUE)
+ CloseHandle(h);
+ return ret;
}
/*
h = CreateFile(path, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't open file for writing", path);
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't open file for writing", path);
return WIMLIB_ERR_OPEN;
}
+ SetLastError(0);
if (!WriteFile(h, contents, size, &bytes_written, NULL) ||
bytes_written != size)
{
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't write file", path);
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't write file", path);
CloseHandle(h);
return WIMLIB_ERR_WRITE;
}
if (!CloseHandle(h)) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't close handle", path);
+ win32_error(GetLastError(),
+ L"\"%ls\": Can't close handle", path);
return WIMLIB_ERR_WRITE;
}
fill_in_wimoverlay_dat(u8 *buf,
const struct WimOverlay_dat_header *old_hdr,
const wchar_t *wim_path,
- const u8 wim_guid[WIM_GUID_LEN],
+ const u8 wim_guid[GUID_SIZE],
int image,
u64 new_data_source_id,
const PARTITION_INFORMATION_EX *part_info,
new_entry_1->entry_2_length = new_entry_2_size;
new_entry_1->wim_type = WIM_BOOT_NOT_OS_WIM;
new_entry_1->wim_index = image;
- BUILD_BUG_ON(sizeof(new_entry_1->guid) != WIM_GUID_LEN);
- memcpy(new_entry_1->guid, wim_guid, WIM_GUID_LEN);
+ STATIC_ASSERT(sizeof(new_entry_1->guid) == GUID_SIZE);
+ copy_guid(new_entry_1->guid, wim_guid);
p += sizeof(struct WimOverlay_dat_entry_1);
new_entry_2->disk.mbr.padding[1] = 0x00000000;
new_entry_2->disk.mbr.padding[2] = 0x00000000;
} else {
- BUILD_BUG_ON(sizeof(new_entry_2->partition.gpt.part_unique_guid) !=
- sizeof(part_info->Gpt.PartitionId));
+ STATIC_ASSERT(sizeof(new_entry_2->partition.gpt.part_unique_guid) ==
+ sizeof(part_info->Gpt.PartitionId));
memcpy(new_entry_2->partition.gpt.part_unique_guid,
&part_info->Gpt.PartitionId,
sizeof(part_info->Gpt.PartitionId));
new_entry_2->partition_table_type = WIMOVERLAY_PARTITION_TYPE_GPT;
- BUILD_BUG_ON(sizeof(new_entry_2->disk.gpt.disk_guid) !=
- sizeof(disk_info->Gpt.DiskId));
+ STATIC_ASSERT(sizeof(new_entry_2->disk.gpt.disk_guid) ==
+ sizeof(disk_info->Gpt.DiskId));
memcpy(new_entry_2->disk.gpt.disk_guid,
&disk_info->Gpt.DiskId,
sizeof(disk_info->Gpt.DiskId));
- BUILD_BUG_ON(sizeof(new_entry_2->disk.gpt.disk_guid) !=
- sizeof(new_entry_2->partition.gpt.part_unique_guid));
+ STATIC_ASSERT(sizeof(new_entry_2->disk.gpt.disk_guid) ==
+ sizeof(new_entry_2->partition.gpt.part_unique_guid));
}
new_entry_2->unknown_0x58[0] = 0x00000000;
new_entry_2->unknown_0x58[1] = 0x00000000;
static int
prepare_wimoverlay_dat(const struct WimOverlay_dat_header *old_hdr,
const wchar_t *wim_path,
- const u8 wim_guid[WIM_GUID_LEN],
+ const u8 wim_guid[GUID_SIZE],
int image,
void **new_contents_ret,
u32 *new_contents_size_ret,
err = err2;
}
}
- set_errno_from_win32_error(err);
- ERROR_WITH_ERRNO("\"%ls\": Can't open for reading", path);
+ win32_error(err, L"\"%ls\": Can't open for reading", path);
return WIMLIB_ERR_OPEN;
}
if (!GetFileInformationByHandle(h, &info)) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't query metadata", path);
+ win32_error(GetLastError(), L"\"%ls\": Can't query metadata", path);
CloseHandle(h);
return WIMLIB_ERR_STAT;
}
return WIMLIB_ERR_NOMEM;
}
+ SetLastError(0);
if (!ReadFile(h, contents, info.nFileSizeLow, &bytes_read, NULL) ||
bytes_read != info.nFileSizeLow)
{
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't read data", path);
+ win32_error(GetLastError(), L"\"%ls\": Can't read data", path);
CloseHandle(h);
ret = WIMLIB_ERR_READ;
goto out_free_contents;
if (wimlib_print_errors) {
print_byte_field((const u8 *)hdr,
sizeof(struct WimOverlay_dat_header),
- stderr);
- fputc('\n', stderr);
+ wimlib_error_file);
+ fputc('\n', wimlib_error_file);
}
ret = WIMLIB_ERR_UNSUPPORTED;
goto out_free_contents;
path, i, entry_1->data_source_id);
if (wimlib_print_errors) {
print_byte_field((const u8 *)entry_2->wim_file_name,
- wim_file_name_length, stderr);
- fputc('\n', stderr);
+ wim_file_name_length,
+ wimlib_error_file);
+ fputc('\n', wimlib_error_file);
}
ret = WIMLIB_ERR_UNSUPPORTED;
goto out_free_contents;
if (wimlib_print_errors) {
print_byte_field((const u8 *)entry_2,
entry_1->entry_2_length,
- stderr);
- fputc('\n', stderr);
+ wimlib_error_file);
+ fputc('\n', wimlib_error_file);
}
ret = WIMLIB_ERR_UNSUPPORTED;
goto out_free_contents;
*/
static int
update_wimoverlay_manually(const wchar_t *drive, const wchar_t *wim_path,
- const u8 wim_guid[WIM_GUID_LEN],
+ const u8 wim_guid[GUID_SIZE],
int image, u64 *data_source_id_ret)
{
wchar_t path_main[] = L"A:\\System Volume Information\\WimOverlay.dat";
wchar_t path_backup[] = L"A:\\System Volume Information\\WimOverlay.backup";
wchar_t path_wimlib_backup[] = L"A:\\System Volume Information\\WimOverlay.wimlib_backup";
wchar_t path_new[] = L"A:\\System Volume Information\\WimOverlay.wimlib_new";
- void *old_contents;
- void *new_contents;
- u32 new_contents_size;
- u64 new_data_source_id;
+ void *old_contents = NULL;
+ void *new_contents = NULL;
+ u32 new_contents_size = 0;
+ u64 new_data_source_id = -1;
int ret;
wimlib_assert(drive[0] != L'\0' &&
if (ret) {
ERROR_WITH_ERRNO("Can't rename \"%ls\" => \"%ls\"",
path_main, path_wimlib_backup);
+ ret = WIMLIB_ERR_RENAME;
goto out_free_new_contents;
}
}
if (ret) {
ERROR_WITH_ERRNO("Can't rename \"%ls\" => \"%ls\"",
path_new, path_main);
+ ret = WIMLIB_ERR_RENAME;
}
out_free_new_contents:
FREE(new_contents);
return ret;
}
-static int
-win32_get_drive_path(const wchar_t *file_path, wchar_t drive_path[7])
-{
- tchar *file_abspath;
-
- file_abspath = realpath(file_path, NULL);
- if (!file_abspath)
- return WIMLIB_ERR_NOMEM;
-
- if (file_abspath[0] == L'\0' || file_abspath[1] != L':') {
- ERROR("\"%ls\": Path format not recognized", file_abspath);
- FREE(file_abspath);
- return WIMLIB_ERR_UNSUPPORTED;
- }
-
- wsprintf(drive_path, L"\\\\.\\%lc:", file_abspath[0]);
- FREE(file_abspath);
- return 0;
-}
-
-/* Try to attach an instance of the Windows Overlay File System Filter Driver to
- * the specified drive (such as C:) */
-static bool
-try_to_attach_wof(const wchar_t *drive)
-{
- HMODULE fltlib;
- bool retval = false;
-
- /* Use FilterAttach() from Fltlib.dll. */
-
- fltlib = LoadLibrary(L"Fltlib.dll");
-
- if (!fltlib) {
- WARNING("Failed to load Fltlib.dll");
- return retval;
- }
-
- HRESULT (WINAPI *func_FilterAttach)(LPCWSTR lpFilterName,
- LPCWSTR lpVolumeName,
- LPCWSTR lpInstanceName,
- DWORD dwCreatedInstanceNameLength,
- LPWSTR lpCreatedInstanceName);
-
- func_FilterAttach = (void *)GetProcAddress(fltlib, "FilterAttach");
-
- if (func_FilterAttach) {
- HRESULT res;
-
- res = (*func_FilterAttach)(L"WoF", drive, NULL, 0, NULL);
-
- if (res == S_OK)
- retval = true;
- } else {
- WARNING("FilterAttach() does not exist in Fltlib.dll");
- }
-
- FreeLibrary(fltlib);
-
- return retval;
-}
-
/*
* Allocate a WOF data source ID for a WIM file.
*
*/
int
wimboot_alloc_data_source_id(const wchar_t *wim_path,
- const u8 wim_guid[WIM_GUID_LEN],
+ const u8 wim_guid[GUID_SIZE],
int image, const wchar_t *target,
u64 *data_source_id_ret, bool *wof_running_ret)
{
h = open_file(drive_path, GENERIC_WRITE);
if (h == INVALID_HANDLE_VALUE) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("Failed to open \"%ls\"", drive_path + 4);
+ win32_error(GetLastError(),
+ L"Failed to open \"%ls\"", drive_path + 4);
ret = WIMLIB_ERR_OPEN;
goto out_free_in;
}
CloseHandle(h);
h = INVALID_HANDLE_VALUE;
tried_to_attach_wof = true;
- if (try_to_attach_wof(drive_path + 4))
+ if (win32_try_to_attach_wof(drive_path + 4))
goto retry_ioctl;
}
ret = WIMLIB_ERR_UNSUPPORTED;
goto out_close_handle;
} else {
- set_errno_from_win32_error(err);
- ERROR_WITH_ERRNO("Failed to add overlay source \"%ls\" "
- "to volume \"%ls\" (err=0x%08"PRIx32")",
- wim_path, drive_path + 4, (u32)err);
+ win32_error(err, L"Failed to add overlay source \"%ls\" "
+ "to volume \"%ls\"", wim_path, drive_path + 4);
ret = WIMLIB_ERR_WIMBOOT;
goto out_close_handle;
}
}
if (bytes_returned != sizeof(data_source_id)) {
- set_errno_from_win32_error(ERROR_INVALID_DATA);
ret = WIMLIB_ERR_WIMBOOT;
ERROR("Unexpected result size when adding "
"overlay source \"%ls\" to volume \"%ls\"",
* This turns it into a reparse point that redirects accesses to it, to the
* corresponding resource in the WIM archive.
*
- * @attr
- * Object attributes that specify the path to the file.
- * @printable_name
- * Printable representation of the path encoded in @attr.
- * @lte
- * Unnamed data stream of the file.
+ * @h
+ * Open handle to the file, with GENERIC_WRITE access.
+ * @blob
+ * The blob for the unnamed data stream of the file.
* @data_source_id
* Allocated identifier for the WIM data source on the destination volume.
- * @lookup_table_hash
- * SHA-1 message digest of the WIM's lookup table.
+ * @blob_table_hash
+ * SHA-1 message digest of the WIM's blob table.
* @wof_running
* %true if the WOF driver appears to be available and working; %false if
* not.
*
- * Returns 0 on success, or a positive error code on failure.
+ * Returns %true on success, or %false on failure with GetLastError() set.
*/
-int
-wimboot_set_pointer(OBJECT_ATTRIBUTES *attr,
- const wchar_t *printable_name,
- const struct wim_lookup_table_entry *lte,
+bool
+wimboot_set_pointer(HANDLE h,
+ const struct blob_descriptor *blob,
u64 data_source_id,
- const u8 lookup_table_hash[SHA1_HASH_SIZE],
+ const u8 blob_table_hash[SHA1_HASH_SIZE],
bool wof_running)
{
- int ret;
- HANDLE h = NULL;
- NTSTATUS status;
- IO_STATUS_BLOCK iosb;
DWORD bytes_returned;
- DWORD err;
-
- status = (*func_NtOpenFile)(&h, GENERIC_WRITE | SYNCHRONIZE, attr,
- &iosb, FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT |
- FILE_OPEN_REPARSE_POINT |
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(status)) {
- SetLastError((*func_RtlNtStatusToDosError)(status));
- goto fail;
- }
if (wof_running) {
/* The WOF driver is running. We can create the reparse point
* using FSCTL_SET_EXTERNAL_BACKING. */
-
+ unsigned int max_retries = 4;
struct {
struct wof_external_info wof_info;
struct 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.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.resource_hash, lte->hash);
+ copy_hash(in.wim_info.unnamed_data_stream_hash, blob->hash);
- /* lookup_table_hash is not necessary */
+ /* blob_table_hash is not necessary */
if (!DeviceIoControl(h, FSCTL_SET_EXTERNAL_BACKING,
&in, sizeof(in), NULL, 0,
&bytes_returned, NULL))
- goto fail;
+ {
+ /* Try to track down sporadic errors */
+ if (wimlib_print_errors) {
+ WARNING("FSCTL_SET_EXTERNAL_BACKING failed (err=%u); data was %zu bytes:",
+ (u32)GetLastError(), sizeof(in));
+ print_byte_field((const u8 *)&in, sizeof(in), wimlib_error_file);
+ putc('\n', wimlib_error_file);
+ }
+ if (--max_retries) {
+ WARNING("Retrying after 100ms...");
+ Sleep(100);
+ goto retry;
+ }
+ WARNING("Too many retries; returning failure");
+ return false;
+ }
} else {
/* The WOF driver is running. We need to create the reparse
struct wim_provider_rpdata wim_info;
} in;
- BUILD_BUG_ON(sizeof(in) != 8 +
- sizeof(struct wof_external_info) +
- sizeof(struct wim_provider_rpdata));
+ STATIC_ASSERT(sizeof(in) == 8 +
+ sizeof(struct wof_external_info) +
+ sizeof(struct wim_provider_rpdata));
- in.hdr.rptag = WIMLIB_REPARSE_TAG_WOF;
+ in.hdr.rptag = WIM_IO_REPARSE_TAG_WOF;
in.hdr.rpdatalen = sizeof(in) - sizeof(in.hdr);
in.hdr.rpreserved = 0;
in.wim_info.version = 2;
in.wim_info.flags = 0;
in.wim_info.data_source_id = data_source_id;
- copy_hash(in.wim_info.resource_hash, lte->hash);
- copy_hash(in.wim_info.wim_lookup_table_hash, lookup_table_hash);
- in.wim_info.stream_uncompressed_size = lte->size;
- in.wim_info.stream_compressed_size = lte->rspec->size_in_wim;
- in.wim_info.stream_offset_in_wim = lte->rspec->offset_in_wim;
+ copy_hash(in.wim_info.unnamed_data_stream_hash, blob->hash);
+ copy_hash(in.wim_info.blob_table_hash, blob_table_hash);
+ in.wim_info.unnamed_data_stream_size = blob->size;
+ in.wim_info.unnamed_data_stream_size_in_wim = blob->rdesc->size_in_wim;
+ in.wim_info.unnamed_data_stream_offset_in_wim = blob->rdesc->offset_in_wim;
if (!DeviceIoControl(h, FSCTL_SET_REPARSE_POINT,
&in, sizeof(in), NULL, 0, &bytes_returned, NULL))
- goto fail;
+ return false;
/* We also need to create an unnamed data stream of the correct
* size. Otherwise the file shows up as zero length. It can be
* are unimportant. */
if (!DeviceIoControl(h, FSCTL_SET_SPARSE, NULL, 0, NULL, 0,
&bytes_returned, NULL))
- goto fail;
+ return false;
if (!SetFilePointerEx(h,
- (LARGE_INTEGER){ .QuadPart = lte->size},
+ (LARGE_INTEGER){ .QuadPart = blob->size},
NULL, FILE_BEGIN))
- goto fail;
+ return false;
if (!SetEndOfFile(h))
- goto fail;
+ return false;
}
- ret = 0;
- goto out;
-
-fail:
- err = GetLastError();
- set_errno_from_win32_error(err);
- ERROR_WITH_ERRNO("\"%ls\": Couldn't set WIMBoot pointer data "
- "(err=%"PRIu32")", printable_name, (u32)err);
- ret = WIMLIB_ERR_WIMBOOT;
-out:
- if (h)
- (*func_NtClose)(h);
- return ret;
-
+ return true;
}
+
+#endif /* __WIN32__ */