* will be assigned later by assign_inode_numbers(). */
dentry->d_inode->i_resolved = 1;
dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ *dentry_ret = dentry;
}
return ret;
}
}
DEBUG("Building dentry tree.");
- if (num_sources == 0) {
- ret = new_filler_directory("", &root_dentry);
+ root_dentry = NULL;
+
+ for (size_t i = 0; i < num_sources; i++) {
+ int flags;
+ union wimlib_progress_info progress;
+
+ DEBUG("Building dentry tree for source %zu of %zu "
+ "(\"%s\" => \"%s\")", i + 1, num_sources,
+ sources[i].fs_source_path,
+ sources[i].wim_target_path);
+ if (progress_func) {
+ memset(&progress, 0, sizeof(progress));
+ progress.scan.source = sources[i].fs_source_path;
+ progress.scan.wim_target_path = sources[i].wim_target_path;
+ progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, &progress);
+ }
+ ret = capture_config_set_prefix(&config,
+ sources[i].fs_source_path);
if (ret)
- goto out_free_security_data;
- } else {
- size_t i;
-
- #ifdef __WIN32__
- win32_acquire_capture_privileges();
- #endif
+ goto out_free_dentry_tree;
+ flags = add_image_flags | WIMLIB_ADD_IMAGE_FLAG_SOURCE;
+ if (!*sources[i].wim_target_path)
+ flags |= WIMLIB_ADD_IMAGE_FLAG_ROOT;
+ ret = (*capture_tree)(&branch, sources[i].fs_source_path,
+ w->lookup_table, sd,
+ &config,
+ flags,
+ progress_func, extra_arg);
+ if (ret) {
+ ERROR("Failed to build dentry tree for `%s'",
+ sources[i].fs_source_path);
+ goto out_free_dentry_tree;
+ }
+ if (branch) {
+ /* Use the target name, not the source name, for
+ * the root of each branch from a capture
+ * source. (This will also set the root dentry
+ * of the entire image to be unnamed.) */
+ ret = set_dentry_name(branch,
+ path_basename(sources[i].wim_target_path));
+ if (ret)
+ goto out_free_branch;
- root_dentry = NULL;
- i = 0;
- do {
- int flags;
- union wimlib_progress_info progress;
-
- DEBUG("Building dentry tree for source %zu of %zu "
- "(\"%s\" => \"%s\")", i + 1, num_sources,
- sources[i].fs_source_path,
- sources[i].wim_target_path);
- if (progress_func) {
- memset(&progress, 0, sizeof(progress));
- progress.scan.source = sources[i].fs_source_path;
- progress.scan.wim_target_path = sources[i].wim_target_path;
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, &progress);
- }
- ret = capture_config_set_prefix(&config,
- sources[i].fs_source_path);
+ ret = attach_branch(&root_dentry, branch,
+ sources[i].wim_target_path);
if (ret)
- goto out_free_dentry_tree;
- flags = add_image_flags | WIMLIB_ADD_IMAGE_FLAG_SOURCE;
- if (!*sources[i].wim_target_path)
- flags |= WIMLIB_ADD_IMAGE_FLAG_ROOT;
- ret = (*capture_tree)(&branch, sources[i].fs_source_path,
- w->lookup_table, sd,
- &config,
- flags,
- progress_func, extra_arg);
- if (ret) {
- ERROR("Failed to build dentry tree for `%s'",
- sources[i].fs_source_path);
- goto out_free_dentry_tree;
- }
- if (branch) {
- /* Use the target name, not the source name, for
- * the root of each branch from a capture
- * source. (This will also set the root dentry
- * of the entire image to be unnamed.) */
- ret = set_dentry_name(branch,
- path_basename(sources[i].wim_target_path));
- if (ret)
- goto out_free_branch;
-
- ret = attach_branch(&root_dentry, branch,
- sources[i].wim_target_path);
- if (ret)
- goto out_free_branch;
- }
- if (progress_func)
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, &progress);
- } while (++i != num_sources);
+ goto out_free_branch;
+ }
+ if (progress_func)
+ progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, &progress);
+ }
+
+ if (root_dentry == NULL) {
+ ret = new_filler_directory("" , &root_dentry);
+ if (ret)
+ goto out_free_dentry_tree;
}
DEBUG("Calculating full paths of dentries.");
out_destroy_capture_config:
destroy_capture_config(&config);
out:
-#ifdef __WIN32__
- win32_release_capture_privileges();
-#endif
return ret;
}
#include "dentry.h"
#include "lookup_table.h"
#include "security.h"
+#include "endianness.h"
#include <errno.h>
#ifdef ENABLE_ERROR_MESSAGES
-void win32_error(u32 err_code)
+void
+win32_error(u32 err_code)
{
char *buffer;
DWORD nchars;
LocalFree(buffer);
}
}
+
+void
+win32_error_last()
+{
+ win32_error(GetLastError());
+}
#endif
-void *win32_open_file_readonly(const void *path)
+HANDLE
+win32_open_file_readonly(const wchar_t *path, bool data_only)
{
- return CreateFileW((const wchar_t*)path,
- FILE_READ_DATA |
- FILE_READ_ATTRIBUTES |
- READ_CONTROL |
- ACCESS_SYSTEM_SECURITY,
+ DWORD dwDesiredAccess = FILE_READ_DATA;
+ if (!data_only)
+ dwDesiredAccess |= FILE_READ_ATTRIBUTES | READ_CONTROL | ACCESS_SYSTEM_SECURITY;
+ return CreateFileW(path,
+ dwDesiredAccess,
FILE_SHARE_READ,
NULL, /* lpSecurityAttributes */
OPEN_EXISTING,
NULL /* hTemplateFile */);
}
-int win32_read_file(const char *filename,
- void *handle, u64 offset, size_t size, void *buf)
+int
+win32_read_file(const mbchar *filename,
+ void *handle, u64 offset, size_t size, void *buf)
{
HANDLE h = handle;
DWORD err;
return WIMLIB_ERR_READ;
}
-void win32_close_file(void *handle)
+void
+win32_close_file(void *handle)
{
CloseHandle((HANDLE)handle);
}
-static bool win32_modify_privilege(const char *privilege, bool enable)
-{
- HANDLE hToken;
- LUID luid;
- TOKEN_PRIVILEGES newState;
- bool ret = false;
-
- DEBUG("%s privilege %s",
- enable ? "Enabling" : "Disabling", privilege);
-
- if (!OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken))
- {
- DEBUG("OpenProcessToken() failed");
- goto out;
- }
-
- if (!LookupPrivilegeValue(NULL, privilege, &luid)) {
- DEBUG("LookupPrivilegeValue() failed");
- goto out;
- }
-
- newState.PrivilegeCount = 1;
- newState.Privileges[0].Luid = luid;
- newState.Privileges[0].Attributes = (enable ? SE_PRIVILEGE_ENABLED : 0);
- ret = AdjustTokenPrivileges(hToken, FALSE, &newState, 0, NULL, NULL);
- if (!ret)
- DEBUG("AdjustTokenPrivileges() failed");
- CloseHandle(hToken);
-out:
- if (!ret) {
- DWORD err = GetLastError();
- win32_error(err);
- WARNING("Failed to %s privilege %s",
- enable ? "enable" : "disable", privilege);
- WARNING("The program will continue, but if permission issues are "
- "encountered, you may need to run this program as the administrator");
- }
- return ret;
-}
-
-static bool win32_acquire_privilege(const char *privilege)
-{
- return win32_modify_privilege(privilege, true);
-}
-
-static bool win32_release_privilege(const char *privilege)
-{
- return win32_modify_privilege(privilege, false);
-}
-
-
-void win32_acquire_capture_privileges()
-{
- win32_acquire_privilege(SE_BACKUP_NAME);
- win32_acquire_privilege(SE_SECURITY_NAME);
-}
-
-void win32_release_capture_privileges()
-{
- win32_release_privilege(SE_BACKUP_NAME);
- win32_release_privilege(SE_SECURITY_NAME);
-}
-
-void win32_acquire_restore_privileges()
-{
- win32_acquire_privilege(SE_RESTORE_NAME);
- win32_acquire_privilege(SE_SECURITY_NAME);
- win32_acquire_privilege(SE_TAKE_OWNERSHIP_NAME);
-}
-
-void win32_release_restore_privileges()
-{
- win32_release_privilege(SE_RESTORE_NAME);
- win32_release_privilege(SE_SECURITY_NAME);
- win32_release_privilege(SE_TAKE_OWNERSHIP_NAME);
-}
-
-static u64 FILETIME_to_u64(const FILETIME *ft)
+static u64
+FILETIME_to_u64(const FILETIME *ft)
{
return ((u64)ft->dwHighDateTime << 32) | (u64)ft->dwLowDateTime;
}
-static int win32_get_short_name(struct wim_dentry *dentry,
- const wchar_t *path_utf16)
+static int
+win32_get_short_name(struct wim_dentry *dentry,
+ const wchar_t *path_utf16)
{
WIN32_FIND_DATAW dat;
if (FindFirstFileW(path_utf16, &dat) &&
dat.cAlternateFileName[0] != L'\0')
{
- size_t short_name_len = wcslen(dat.cAlternateFileName) * 2;
- size_t n = short_name_len + sizeof(wchar_t);
+ size_t short_name_nbytes = wcslen(dat.cAlternateFileName) * 2;
+ size_t n = short_name_nbytes + sizeof(wchar_t);
dentry->short_name = MALLOC(n);
if (!dentry->short_name)
return WIMLIB_ERR_NOMEM;
memcpy(dentry->short_name, dat.cAlternateFileName, n);
- dentry->short_name_len = short_name_len;
+ dentry->short_name_nbytes = short_name_nbytes;
}
return 0;
}
-static int win32_get_security_descriptor(struct wim_dentry *dentry,
- struct sd_set *sd_set,
- const wchar_t *path_utf16)
+static int
+win32_get_security_descriptor(struct wim_dentry *dentry,
+ struct sd_set *sd_set,
+ const wchar_t *path_utf16)
{
SECURITY_INFORMATION requestedInformation;
DWORD lenNeeded = 0;
/* Reads the directory entries of directory using a Win32 API and recursively
* calls win32_build_dentry_tree() on them. */
-static int win32_recurse_directory(struct wim_dentry *root,
- const char *root_disk_path,
- struct wim_lookup_table *lookup_table,
- struct wim_security_data *sd,
- const struct capture_config *config,
- int add_image_flags,
- wimlib_progress_func_t progress_func,
- struct sd_set *sd_set,
- const wchar_t *path_utf16,
- size_t path_utf16_nchars)
+static int
+win32_recurse_directory(struct wim_dentry *root,
+ const mbchar *root_disk_path,
+ struct wim_lookup_table *lookup_table,
+ struct wim_security_data *sd,
+ const struct capture_config *config,
+ int add_image_flags,
+ wimlib_progress_func_t progress_func,
+ struct sd_set *sd_set,
+ const wchar_t *path_utf16,
+ size_t path_utf16_nchars)
{
WIN32_FIND_DATAW dat;
HANDLE hFind;
{
struct wim_dentry *child;
- char *utf8_name;
- size_t utf8_name_nbytes;
- ret = utf16_to_utf8((const char*)dat.cFileName,
- wcslen(dat.cFileName) * sizeof(wchar_t),
- &utf8_name,
- &utf8_name_nbytes);
+ char *mbs_name;
+ size_t mbs_name_nbytes;
+ ret = utf16le_to_mbs(dat.cFileName,
+ wcslen(dat.cFileName) * sizeof(wchar_t),
+ &mbs_name,
+ &mbs_name_nbytes);
if (ret)
goto out_find_close;
- char name[strlen(root_disk_path) + 1 + utf8_name_nbytes + 1];
- sprintf(name, "%s/%s", root_disk_path, utf8_name);
- FREE(utf8_name);
+ char 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,
sd, config, add_image_flags,
progress_func, sd_set);
* only.
*
* Returns 0 on success; nonzero on failure. */
-static int win32_capture_reparse_point(HANDLE hFile,
- struct wim_inode *inode,
- struct wim_lookup_table *lookup_table,
- const char *path)
+static int
+win32_capture_reparse_point(HANDLE hFile,
+ struct wim_inode *inode,
+ struct wim_lookup_table *lookup_table,
+ const char *path)
{
/* "Reparse point data, including the tag and optional GUID,
* cannot exceed 16 kilobytes." - MSDN */
ERROR("Reparse data on \"%s\" is invalid", path);
return WIMLIB_ERR_READ;
}
- inode->i_reparse_tag = *(u32*)reparse_point_buf;
+ inode->i_reparse_tag = le32_to_cpu(*(u32*)reparse_point_buf);
return inode_add_ads_with_data(inode, "",
(const u8*)reparse_point_buf + 8,
bytesReturned - 8, lookup_table);
*
* Returns 0 on success; nonzero on failure.
*/
-static int win32_sha1sum(const wchar_t *path, u8 hash[SHA1_HASH_SIZE])
+static int
+win32_sha1sum(const wchar_t *path, u8 hash[SHA1_HASH_SIZE])
{
HANDLE hFile;
SHA_CTX ctx;
DWORD bytesRead;
int ret;
- hFile = win32_open_file_readonly(path);
+ hFile = win32_open_file_readonly(path, false);
if (hFile == INVALID_HANDLE_VALUE)
return WIMLIB_ERR_OPEN;
*
* Returns 0 on success; nonzero on failure.
*/
-static int win32_capture_stream(const wchar_t *path_utf16,
- size_t path_utf16_nchars,
- struct wim_inode *inode,
- struct wim_lookup_table *lookup_table,
- WIN32_FIND_STREAM_DATA *dat)
+static int
+win32_capture_stream(const wchar_t *path_utf16,
+ size_t path_utf16_nchars,
+ struct wim_inode *inode,
+ struct wim_lookup_table *lookup_table,
+ WIN32_FIND_STREAM_DATA *dat)
{
struct wim_ads_entry *ads_entry;
u8 hash[SHA1_HASH_SIZE];
is_named_stream = (p != colon);
if (is_named_stream) {
/* Allocate an ADS entry for the named stream. */
- char *utf8_stream_name;
- size_t utf8_stream_name_len;
- ret = utf16_to_utf8((const char *)p,
- (colon - p) * sizeof(wchar_t),
- &utf8_stream_name,
- &utf8_stream_name_len);
+ char *mbs_stream_name;
+ size_t mbs_stream_name_nbytes;
+ ret = utf16le_to_mbs(p,
+ (colon - p) * sizeof(wchar_t),
+ &mbs_stream_name,
+ &mbs_stream_name_nbytes);
if (ret)
goto out;
- ads_entry = inode_add_ads(inode, utf8_stream_name);
- FREE(utf8_stream_name);
+ ads_entry = inode_add_ads(inode, mbs_stream_name);
+ FREE(mbs_stream_name);
if (!ads_entry) {
ret = WIMLIB_ERR_NOMEM;
goto out;
ret = WIMLIB_ERR_NOMEM;
goto out_free_spath;
}
- lte->file_on_disk = (char*)spath;
+ lte->win32_file_on_disk = spath;
+ lte->file_on_disk_fp = INVALID_HANDLE_VALUE;
spath = NULL;
lte->resource_location = RESOURCE_WIN32;
lte->resource_entry.original_size = (uint64_t)dat->StreamSize.QuadPart;
*
* Returns 0 on success; nonzero on failure.
*/
-static int win32_capture_streams(const wchar_t *path_utf16,
- size_t path_utf16_nchars,
- struct wim_inode *inode,
- struct wim_lookup_table *lookup_table)
+static int
+win32_capture_streams(const wchar_t *path_utf16,
+ size_t path_utf16_nchars,
+ struct wim_inode *inode,
+ struct wim_lookup_table *lookup_table)
{
WIN32_FIND_STREAM_DATA dat;
int ret;
}
/* Win32 version of capturing a directory tree */
-int win32_build_dentry_tree(struct wim_dentry **root_ret,
- const char *root_disk_path,
- struct wim_lookup_table *lookup_table,
- struct wim_security_data *sd,
- const struct capture_config *config,
- int add_image_flags,
- wimlib_progress_func_t progress_func,
- void *extra_arg)
+int
+win32_build_dentry_tree(struct wim_dentry **root_ret,
+ const char *root_disk_path,
+ struct wim_lookup_table *lookup_table,
+ struct wim_security_data *sd,
+ const struct capture_config *config,
+ int add_image_flags,
+ wimlib_progress_func_t progress_func,
+ void *extra_arg)
{
struct wim_dentry *root = NULL;
int ret = 0;
struct wim_inode *inode;
wchar_t *path_utf16;
+ size_t path_utf16_nbytes;
size_t path_utf16_nchars;
struct sd_set *sd_set;
DWORD err;
sd_set = extra_arg;
}
- ret = utf8_to_utf16(root_disk_path, strlen(root_disk_path),
- (char**)&path_utf16, &path_utf16_nchars);
+ ret = mbs_to_utf16le(root_disk_path, strlen(root_disk_path),
+ &path_utf16, &path_utf16_nbytes);
if (ret)
goto out_destroy_sd_set;
- path_utf16_nchars /= sizeof(wchar_t);
+ path_utf16_nchars = path_utf16_nbytes / sizeof(wchar_t);
- HANDLE hFile = win32_open_file_readonly(path_utf16);
+ HANDLE hFile = win32_open_file_readonly(path_utf16, false);
if (hFile == INVALID_HANDLE_VALUE) {
err = GetLastError();
ERROR("Win32 API: Failed to open \"%s\"", root_disk_path);
}
/* Create a WIM dentry */
- root = new_dentry_with_timeless_inode(path_basename(root_disk_path));
- if (!root) {
- if (errno == EILSEQ)
- ret = WIMLIB_ERR_INVALID_UTF8_STRING;
- else if (errno == ENOMEM)
- ret = WIMLIB_ERR_NOMEM;
- else
- ret = WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+ ret = new_dentry_with_timeless_inode(path_basename(root_disk_path), &root);
+ if (ret)
goto out_close_handle;
- }
/* Start preparing the associated WIM inode */
inode = root->d_inode;
}
/* Replacement for POSIX fnmatch() (partial functionality only) */
-int fnmatch(const char *pattern, const char *string, int flags)
+int
+fnmatch(const char *pattern, const char *string, int flags)
{
if (PathMatchSpecA(string, pattern))
return 0;
return FNM_NOMATCH;
}
-static int win32_set_reparse_data(HANDLE h,
- u32 reparse_tag,
- const struct wim_lookup_table_entry *lte,
- const wchar_t *path)
+static int
+win32_set_reparse_data(HANDLE h,
+ u32 reparse_tag,
+ const struct wim_lookup_table_entry *lte,
+ const wchar_t *path)
{
int ret;
u8 *buf;
ret = read_full_wim_resource(lte, buf + 8, 0);
if (ret)
return ret;
- *(u32*)(buf + 0) = reparse_tag;
- *(u16*)(buf + 4) = len;
+ *(u32*)(buf + 0) = cpu_to_le32(reparse_tag);
+ *(u16*)(buf + 4) = cpu_to_le16(len);
*(u16*)(buf + 6) = 0;
/* Set the reparse data on the open file using the
}
-static int win32_extract_chunk(const u8 *buf, size_t len, u64 offset, void *arg)
+static int
+win32_extract_chunk(const void *buf, size_t len, u64 offset, void *arg)
{
HANDLE hStream = arg;
return 0;
}
-static int do_win32_extract_stream(HANDLE hStream, struct wim_lookup_table_entry *lte)
+static int
+do_win32_extract_stream(HANDLE hStream, struct wim_lookup_table_entry *lte)
{
return extract_wim_resource(lte, wim_resource_size(lte),
win32_extract_chunk, hStream);
}
-static int win32_extract_stream(const struct wim_inode *inode,
- const wchar_t *path,
- const wchar_t *stream_name_utf16,
- struct wim_lookup_table_entry *lte)
+static int
+win32_extract_stream(const struct wim_inode *inode,
+ const wchar_t *path,
+ const wchar_t *stream_name_utf16,
+ struct wim_lookup_table_entry *lte)
{
wchar_t *stream_path;
HANDLE h;
*
* Returns 0 on success; nonzero on failure.
*/
-static int win32_extract_streams(const struct wim_inode *inode,
- const wchar_t *path, u64 *completed_bytes_p)
+static int
+win32_extract_streams(const struct wim_inode *inode,
+ const wchar_t *path, u64 *completed_bytes_p)
{
struct wim_lookup_table_entry *unnamed_lte;
int ret;
*completed_bytes_p += wim_resource_size(unnamed_lte);
for (u16 i = 0; i < inode->i_num_ads; i++) {
const struct wim_ads_entry *ads_entry = &inode->i_ads_entries[i];
- if (ads_entry->stream_name_len != 0) {
+ if (ads_entry->stream_name_nbytes != 0) {
/* Skip special UNIX data entries (see documentation for
* WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) */
- if (ads_entry->stream_name_len == WIMLIB_UNIX_DATA_TAG_LEN
- && !memcmp(ads_entry->stream_name_utf8,
- WIMLIB_UNIX_DATA_TAG,
- WIMLIB_UNIX_DATA_TAG_LEN))
+ if (ads_entry->stream_name_nbytes == WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES
+ && !memcmp(ads_entry->stream_name,
+ WIMLIB_UNIX_DATA_TAG_UTF16LE,
+ WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES))
continue;
ret = win32_extract_stream(inode,
path,
- (const wchar_t*)ads_entry->stream_name,
+ ads_entry->stream_name,
ads_entry->lte);
if (ret)
break;
/* Extract a file, directory, reparse point, or hard link to an
* already-extracted file using the Win32 API */
-int win32_do_apply_dentry(const char *output_path,
- size_t output_path_len,
+int win32_do_apply_dentry(const mbchar *output_path,
+ size_t output_path_nbytes,
struct wim_dentry *dentry,
struct apply_args *args)
{
- char *utf16_path;
- size_t utf16_path_len;
+ wchar_t *utf16le_path;
+ size_t utf16le_path_nbytes;
DWORD err;
int ret;
struct wim_inode *inode = dentry->d_inode;
- ret = utf8_to_utf16(output_path, output_path_len,
- &utf16_path, &utf16_path_len);
+ ret = mbs_to_utf16le(output_path, output_path_nbytes,
+ &utf16le_path, &utf16le_path_nbytes);
if (ret)
return ret;
/* Linked file, with another name already extracted. Create a
* hard link. */
DEBUG("Creating hard link \"%ls => %ls\"",
- (const wchar_t*)utf16_path,
- (const wchar_t*)inode->i_extracted_file);
- if (!CreateHardLinkW((const wchar_t*)utf16_path,
- (const wchar_t*)inode->i_extracted_file,
- NULL))
+ utf16le_path, inode->i_extracted_file);
+ if (!CreateHardLinkW(utf16le_path, inode->i_extracted_file, NULL))
{
err = GetLastError();
ERROR("Can't create hard link \"%ls => %ls\"",
- (const wchar_t*)utf16_path,
- (const wchar_t*)inode->i_extracted_file);
+ utf16le_path, inode->i_extracted_file);
ret = WIMLIB_ERR_LINK;
win32_error(err);
}
} else {
/* Create the file, directory, or reparse point, and extract the
* data streams. */
- ret = win32_extract_streams(inode, (const wchar_t*)utf16_path,
+ ret = win32_extract_streams(inode, utf16le_path,
&args->progress.extract.completed_bytes);
if (ret)
goto out_free_utf16_path;
DEBUG("Setting security descriptor %d on %s",
inode->i_security_id, output_path);
ret = win32_set_security_data(inode,
- (const wchar_t*)utf16_path,
+ utf16le_path,
wim_const_security_data(args->w));
if (ret)
goto out_free_utf16_path;
/* Save extracted path for a later call to
* CreateHardLinkW() if this inode has multiple links.
* */
- inode->i_extracted_file = utf16_path;
+ inode->i_extracted_file = utf16le_path;
goto out;
}
}
out_free_utf16_path:
- FREE(utf16_path);
+ FREE(utf16le_path);
out:
return ret;
}
/* Set timestamps on an extracted file using the Win32 API */
-int win32_do_apply_dentry_timestamps(const char *output_path,
- size_t output_path_len,
- const struct wim_dentry *dentry,
- const struct apply_args *args)
+int
+win32_do_apply_dentry_timestamps(const mbchar *output_path,
+ size_t output_path_nbytes,
+ const struct wim_dentry *dentry,
+ const struct apply_args *args)
{
/* Win32 */
- char *utf16_path;
- size_t utf16_path_len;
+ wchar_t *utf16le_path;
+ size_t utf16le_path_nbytes;
DWORD err;
HANDLE h;
int ret;
const struct wim_inode *inode = dentry->d_inode;
- ret = utf8_to_utf16(output_path, output_path_len,
- &utf16_path, &utf16_path_len);
+ ret = mbs_to_utf16le(output_path, output_path_nbytes,
+ &utf16le_path, &utf16le_path_nbytes);
if (ret)
return ret;
DEBUG("Opening \"%s\" to set timestamps", output_path);
- h = CreateFileW((const wchar_t*)utf16_path,
+ h = CreateFileW(utf16le_path,
GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY,
FILE_SHARE_READ,
NULL,
if (h == INVALID_HANDLE_VALUE)
err = GetLastError();
- FREE(utf16_path);
+ FREE(utf16le_path);
if (h == INVALID_HANDLE_VALUE)
goto fail;
}
/* Replacement for POSIX fsync() */
-int fsync(int fd)
+int
+fsync(int fd)
{
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (h == INVALID_HANDLE_VALUE) {
+ ERROR("Could not get Windows handle for file descriptor");
+ win32_error(GetLastError());
errno = EBADF;
return -1;
}
if (!FlushFileBuffers(h)) {
+ ERROR("Could not flush file buffers to disk");
+ win32_error(GetLastError());
errno = EIO;
return -1;
}
}
/* Use the Win32 API to get the number of processors */
-unsigned win32_get_number_of_processors()
+unsigned
+win32_get_number_of_processors()
{
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
fail:
return NULL;
}
+
+char *
+nl_langinfo(nl_item item)
+{
+ wimlib_assert(item == CODESET);
+ static char buf[64];
+ strcpy(buf, "Unknown");
+ return buf;
+}