]> wimlib.net Git - wimlib/blobdiff - src/extract_image.c
Windows native build
[wimlib] / src / extract_image.c
index 25f4d917450ece86f753d1c3d20828e359f0f985..86063819ab26c2e363fbbb8257544afc9efa4efc 100644 (file)
 #include <alloca.h>
 #endif
 
+#if defined(__WIN32__)
+#      define swprintf _snwprintf
+#      define mkdir(path, mode) (!CreateDirectoryA(path, NULL))
+#endif
+
 #if defined(__CYGWIN__) || defined(__WIN32__)
 
 static int win32_set_reparse_data(HANDLE h,
@@ -169,19 +174,19 @@ static int win32_extract_stream(const struct wim_inode *inode,
                /* Named stream.  Create a buffer that contains the UTF-16LE
                 * string [./]@path:@stream_name_utf16.  This is needed to
                 * create and open the stream using CreateFileW().  I'm not
-                * aware of any other APIs to do this.  Note: note that the
-                * '$DATA' suffix seems to be unneeded; Additional note: a "./"
-                * prefix needs to be added when the path is not absolute to
-                * avoid ambiguity with drive letters. */
+                * aware of any other APIs to do this.  Note: the '$DATA' suffix
+                * seems to be unneeded.  Additional note: a "./" prefix needs
+                * to be added when the path is not absolute to avoid ambiguity
+                * with drive letters. */
                size_t stream_path_nchars;
                size_t path_nchars;
                size_t stream_name_nchars;
                const wchar_t *prefix;
 
-               path_nchars = wcslen(path);
+               path_nchars = wcslen(path);
                stream_name_nchars = wcslen(stream_name_utf16);
                stream_path_nchars = path_nchars + 1 + stream_name_nchars;
-               if (path[0] != L'/' && path[1] != L'\\') {
+               if (path[0] != L'/' && path[0] != L'\\') {
                        prefix = L"./";
                        stream_path_nchars += 2;
                } else {
@@ -191,8 +196,8 @@ static int win32_extract_stream(const struct wim_inode *inode,
                swprintf(stream_path, stream_path_nchars + 1, L"%ls%ls:%ls",
                         prefix, path, stream_name_utf16);
        } else {
-               /* Unnamed stream; it's path is just the path to the file
-                * itself. */
+               /* Unnamed stream; its path is just the path to the file itself.
+                * */
                stream_path = (wchar_t*)path;
 
                /* Directories must be created with CreateDirectoryW().  Then
@@ -203,7 +208,7 @@ static int win32_extract_stream(const struct wim_inode *inode,
                                err = GetLastError();
                                if (err != ERROR_ALREADY_EXISTS) {
                                        ERROR("Failed to create directory \"%ls\"",
-                                             path);
+                                             stream_path);
                                        win32_error(err);
                                        ret = WIMLIB_ERR_MKDIR;
                                        goto fail;
@@ -245,7 +250,7 @@ static int win32_extract_stream(const struct wim_inode *inode,
                        goto fail_close_handle;
        } else {
                if (lte) {
-                       DEBUG("Extracting \"%ls\" (len = %zu)",
+                       DEBUG("Extracting \"%ls\" (len = %"PRIu64")",
                              stream_path, wim_resource_size(lte));
                        ret = do_win32_extract_stream(h, lte);
                        if (ret)
@@ -324,7 +329,6 @@ out:
  * @inode:     The WIM inode that was extracted and has a security descriptor.
  * @path:      UTF-16LE external path that the inode was extracted to.
  * @sd:                Security data for the WIM image.
- * @path_utf8:  @path in UTF-8 for error messages only.
  *
  * Returns 0 on success; nonzero on failure.
  */
@@ -776,13 +780,12 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
        size_t utf16_path_len;
        DWORD err;
        HANDLE h;
-       BOOL bret1, bret2;
 
        ret = utf8_to_utf16(output_path, len, &utf16_path, &utf16_path_len);
        if (ret)
                return ret;
 
-       DEBUG("Opening \"%ls\" to set timestamps", utf16_path);
+       DEBUG("Opening \"%s\" to set timestamps", output_path);
        h = CreateFileW((const wchar_t*)utf16_path,
                        GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY,
                        FILE_SHARE_READ,
@@ -797,12 +800,12 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg)
        if (h == INVALID_HANDLE_VALUE)
                goto fail;
 
-       FILETIME creationTime = {.dwLowDateTime = dentry->d_inode->i_creation_time & 0xffffffff,
-                                .dwHighDateTime = dentry->d_inode->i_creation_time >> 32};
-       FILETIME lastAccessTime = {.dwLowDateTime = dentry->d_inode->i_last_access_time & 0xffffffff,
-                                 .dwHighDateTime = dentry->d_inode->i_last_access_time >> 32};
-       FILETIME lastWriteTime = {.dwLowDateTime = dentry->d_inode->i_last_write_time & 0xffffffff,
-                                 .dwHighDateTime = dentry->d_inode->i_last_write_time >> 32};
+       FILETIME creationTime = {.dwLowDateTime = inode->i_creation_time & 0xffffffff,
+                                .dwHighDateTime = inode->i_creation_time >> 32};
+       FILETIME lastAccessTime = {.dwLowDateTime = inode->i_last_access_time & 0xffffffff,
+                                 .dwHighDateTime = inode->i_last_access_time >> 32};
+       FILETIME lastWriteTime = {.dwLowDateTime = inode->i_last_write_time & 0xffffffff,
+                                 .dwHighDateTime = inode->i_last_write_time >> 32};
 
        DEBUG("Calling SetFileTime() on \"%s\"", output_path);
        if (!SetFileTime(h, &creationTime, &lastAccessTime, &lastWriteTime)) {
@@ -1320,6 +1323,11 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
                w->lookup_table = joined_tab;
        }
 
+#if defined(__CYGWIN__) || defined(__WIN32__)
+       win32_acquire_privilege(SE_RESTORE_NAME);
+       win32_acquire_privilege(SE_SECURITY_NAME);
+       win32_acquire_privilege(SE_TAKE_OWNERSHIP_NAME);
+#endif
        if (image == WIMLIB_ALL_IMAGES) {
                extract_flags |= WIMLIB_EXTRACT_FLAG_MULTI_IMAGE;
                ret = extract_all_images(w, target, extract_flags,
@@ -1329,6 +1337,11 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w,
                ret = extract_single_image(w, image, target, extract_flags,
                                           progress_func);
        }
+#if defined(__CYGWIN__) || defined(__WIN32__)
+       win32_release_privilege(SE_RESTORE_NAME);
+       win32_release_privilege(SE_SECURITY_NAME);
+       win32_release_privilege(SE_TAKE_OWNERSHIP_NAME);
+#endif
 
        if (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
                             WIMLIB_EXTRACT_FLAG_HARDLINK))