X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwin32.c;h=6d3951f528d82fec050ccbab6ff9814b476091dc;hb=541b65d79e0c73238a25e2c2661711d8593d0684;hp=fb30b5f08d3f29e9577bb05ef29578e92e91e3c2;hpb=9fb3aaca115429b0af2a623bf20bfceef74f047f;p=wimlib diff --git a/src/win32.c b/src/win32.c index fb30b5f0..6d3951f5 100644 --- a/src/win32.c +++ b/src/win32.c @@ -44,6 +44,12 @@ #include +static const char *access_denied_msg = +" If you are not running this program as the administrator, you may\n" +" need to do so, so that all data and metadata can be backed up.\n" +" Otherwise, there may be no way to access the desired data or\n" +" metadata without taking ownership of the file or directory.\n"; + #ifdef ENABLE_ERROR_MESSAGES void win32_error(u32 err_code) @@ -171,10 +177,17 @@ win32_get_security_descriptor(struct wim_dentry *dentry, err = GetLastError(); } } - ERROR("Win32 API: Failed to read security descriptor of \"%ls\"", - path_utf16); - win32_error(err); - return WIMLIB_ERR_READ; + + if (err == ERROR_ACCESS_DENIED) { + WARNING("Failed to read security descriptor of \"%ls\": " + "Access denied!\n%s", path_utf16, access_denied_msg); + return 0; + } else { + ERROR("Win32 API: Failed to read security descriptor of \"%ls\"", + path_utf16); + win32_error(err); + return WIMLIB_ERR_READ; + } } /* Reads the directory entries of directory using a Win32 API and recursively @@ -229,7 +242,7 @@ win32_recurse_directory(struct wim_dentry *root, { struct wim_dentry *child; - char *mbs_name; + mbchar *mbs_name; size_t mbs_name_nbytes; ret = utf16le_to_mbs(dat.cFileName, wcslen(dat.cFileName) * sizeof(wchar_t), @@ -238,7 +251,7 @@ win32_recurse_directory(struct wim_dentry *root, if (ret) goto out_find_close; - char name[strlen(root_disk_path) + 1 + mbs_name_nbytes + 1]; + mbchar name[strlen(root_disk_path) + 1 + mbs_name_nbytes + 1]; sprintf(name, "%s/%s", root_disk_path, mbs_name); FREE(mbs_name); ret = win32_build_dentry_tree(&child, name, lookup_table, @@ -281,7 +294,7 @@ static int win32_capture_reparse_point(HANDLE hFile, struct wim_inode *inode, struct wim_lookup_table *lookup_table, - const char *path) + const mbchar *path) { /* "Reparse point data, including the tag and optional GUID, * cannot exceed 16 kilobytes." - MSDN */ @@ -401,7 +414,7 @@ win32_capture_stream(const wchar_t *path_utf16, is_named_stream = (p != colon); if (is_named_stream) { /* Allocate an ADS entry for the named stream. */ - char *mbs_stream_name; + mbchar *mbs_stream_name; size_t mbs_stream_name_nbytes; ret = utf16le_to_mbs(p, (colon - p) * sizeof(wchar_t), @@ -514,10 +527,17 @@ win32_capture_streams(const wchar_t *path_utf16, { return 0; } else { - ERROR("Win32 API: Failed to look up data streams of \"%ls\"", - path_utf16); - win32_error(err); - return WIMLIB_ERR_READ; + if (err == ERROR_ACCESS_DENIED) { + WARNING("Failed to look up data streams of \"%ls\": " + "Access denied!\n%s", path_utf16, + access_denied_msg); + return 0; + } else { + ERROR("Win32 API: Failed to look up data streams of \"%ls\"", + path_utf16); + win32_error(err); + return WIMLIB_ERR_READ; + } } } do { @@ -542,7 +562,7 @@ out_find_close: /* Win32 version of capturing a directory tree */ int win32_build_dentry_tree(struct wim_dentry **root_ret, - const char *root_disk_path, + const mbchar *root_disk_path, struct wim_lookup_table *lookup_table, struct wim_security_data *sd, const struct capture_config *config, @@ -1183,3 +1203,20 @@ nl_langinfo(nl_item item) strcpy(buf, "Unknown"); return buf; } + +/* rename() on Windows fails if the destination file exists. Fix it. */ +int +rename_replacement(const char *oldpath, const char *newpath) +{ + if (MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING)) { + return 0; + } else { + /* As usual, the possible error values are not documented */ + DWORD err = GetLastError(); + ERROR("MoveFileExA(): Can't rename \"%s\" to \"%s\"", + oldpath, newpath); + win32_error(err); + errno = 0; + return -1; + } +}