X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwin32.c;h=10f28b3d91280106d4955526f30bc8b10ddf0203;hb=5c0d30fbd73ee5e9f080d0763ec08eb68fe69314;hp=b10a4058ab05d2fb654bcbdff72260590d6f52a8;hpb=ca3f717fa42ec38d85dc020821340e59a15c25df;p=wimlib diff --git a/src/win32.c b/src/win32.c index b10a4058..10f28b3d 100644 --- a/src/win32.c +++ b/src/win32.c @@ -46,6 +46,7 @@ #define MAX_GET_SD_ACCESS_DENIED_WARNINGS 1 #define MAX_GET_SACL_PRIV_NOTHELD_WARNINGS 1 +#define MAX_CREATE_HARD_LINK_WARNINGS 5 struct win32_capture_state { unsigned long num_get_sd_access_denied; unsigned long num_get_sacl_priv_notheld; @@ -743,18 +744,11 @@ win32_do_capture_rpfix(char *rpbuf, DWORD *rpbuflen_p, /* Load a reparse point into a WIM inode. It is just stored in memory. * - * @hFile: Open handle to a reparse point, with permission to read the reparse - * data. + * @hFile is the open handle to a reparse point, with permission to read the + * reparse data. * - * @inode: WIM inode for the reparse point. - * - * @lookup_table: Stream lookup table for the WIM; an entry will be added to it - * for the reparse point unless an entry already exists for - * the exact same data stream. - * - * @path: External path to the reparse point. Used for error messages only. - * - * Returns 0 on success; nonzero on failure. */ + * @inode is the WIM inode for the reparse point. + */ static int win32_capture_reparse_point(struct wim_dentry **root_p, HANDLE hFile, @@ -809,8 +803,8 @@ win32_capture_reparse_point(struct wim_dentry **root_p, inode->i_not_rpfixed = 0; } } - return inode_add_ads_with_data(inode, L"", reparse_point_buf + 8, - bytesReturned - 8, params->lookup_table); + return inode_set_unnamed_stream(inode, reparse_point_buf + 8, + bytesReturned - 8, params->lookup_table); } /* Scans an unnamed or named stream of a Win32 file (not a reparse point @@ -1768,7 +1762,7 @@ win32_extract_streams(const struct wim_inode *inode, vol_flags); if (ret) goto out; - if (unnamed_lte) + if (unnamed_lte && inode->i_extracted_file == NULL) *completed_bytes_p += wim_resource_size(unnamed_lte); if (!(vol_flags & FILE_NAMED_STREAMS)) @@ -1790,7 +1784,7 @@ win32_extract_streams(const struct wim_inode *inode, vol_flags); if (ret) break; - if (ads_entry->lte) + if (ads_entry->lte && inode->i_extracted_file == NULL) *completed_bytes_p += wim_resource_size(ads_entry->lte); } } @@ -1865,11 +1859,31 @@ win32_do_apply_dentry(const wchar_t *output_path, win32_error(err); return WIMLIB_ERR_LINK; } else { - WARNING("Can't create hard link \"%ls => %ls\":\n" - " Volume does not support hard links!\n" - " Falling back to extracting a copy of the file."); + args->num_hard_links_failed++; + if (args->num_hard_links_failed < MAX_CREATE_HARD_LINK_WARNINGS) { + WARNING("Can't create hard link \"%ls => %ls\":\n" + " Volume does not support hard links!\n" + " Falling back to extracting a copy of the file.", + output_path, inode->i_extracted_file); + } else if (args->num_hard_links_failed == MAX_CREATE_HARD_LINK_WARNINGS) { + WARNING("Suppressing further hard linking warnings..."); + } } } + + if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT && + !(args->vol_flags & FILE_SUPPORTS_REPARSE_POINTS)) + { + WARNING("Skipping extraction of reparse point \"%ls\":\n" + " Not supported by destination filesystem", + output_path); + struct wim_lookup_table_entry *lte; + lte = inode_unnamed_lte_resolved(inode); + if (lte) + args->progress.extract.completed_bytes += wim_resource_size(lte); + return 0; + } + /* Create the file, directory, or reparse point, and extract the * data streams. */ ret = win32_extract_streams(inode, output_path, @@ -1908,6 +1922,19 @@ win32_do_apply_dentry_timestamps(const wchar_t *path, HANDLE h; const struct wim_inode *inode = dentry->d_inode; + if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT && + !(args->vol_flags & FILE_SUPPORTS_REPARSE_POINTS)) + { + /* Skip reparse points not extracted */ + return 0; + } + + /* Windows doesn't let you change the timestamps of the root directory + * (at least on FAT, which is dumb but expected since FAT doesn't store + * any metadata about the root directory...) */ + if (path_is_root_of_drive(path)) + return 0; + DEBUG("Opening \"%ls\" to set timestamps", path); h = win32_open_existing_file(path, FILE_WRITE_ATTRIBUTES); if (h == INVALID_HANDLE_VALUE) {