]> wimlib.net Git - wimlib/blobdiff - src/win32_capture.c
Use explicit casting in ctype macros
[wimlib] / src / win32_capture.c
index 13f63650e3e46f537696ffbea1614577c0a13227..9d8bbbcb15423925bf8b1d0be26b9410c34580b8 100644 (file)
@@ -106,7 +106,7 @@ retry:
  * described by @blob.  */
 int
 read_winnt_stream_prefix(const struct blob_descriptor *blob, u64 size,
-                        consume_data_callback_t cb, void *cb_ctx)
+                        const struct read_blob_callbacks *cbs)
 {
        const wchar_t *path;
        HANDLE h;
@@ -147,7 +147,7 @@ read_winnt_stream_prefix(const struct blob_descriptor *blob, u64 size,
                bytes_read = iosb.Information;
 
                bytes_remaining -= bytes_read;
-               ret = (*cb)(buf, bytes_read, cb_ctx);
+               ret = call_consume_chunk(buf, bytes_read, cbs);
                if (ret)
                        break;
        }
@@ -156,8 +156,7 @@ read_winnt_stream_prefix(const struct blob_descriptor *blob, u64 size,
 }
 
 struct win32_encrypted_read_ctx {
-       consume_data_callback_t read_prefix_cb;
-       void *read_prefix_ctx;
+       const struct read_blob_callbacks *cbs;
        int wimlib_err_code;
        u64 bytes_remaining;
 };
@@ -172,7 +171,7 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len)
        if (bytes_to_consume == 0)
                return ERROR_SUCCESS;
 
-       ret = (*ctx->read_prefix_cb)(data, bytes_to_consume, ctx->read_prefix_ctx);
+       ret = call_consume_chunk(data, bytes_to_consume, ctx->cbs);
        if (ret) {
                ctx->wimlib_err_code = ret;
                /* It doesn't matter what error code is returned here, as long
@@ -186,7 +185,7 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len)
 int
 read_win32_encrypted_file_prefix(const struct blob_descriptor *blob,
                                 u64 size,
-                                consume_data_callback_t cb, void *cb_ctx)
+                                const struct read_blob_callbacks *cbs)
 {
        struct win32_encrypted_read_ctx export_ctx;
        DWORD err;
@@ -197,8 +196,7 @@ read_win32_encrypted_file_prefix(const struct blob_descriptor *blob,
        if (blob->file_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY)
                flags |= CREATE_FOR_DIR;
 
-       export_ctx.read_prefix_cb = cb;
-       export_ctx.read_prefix_ctx = cb_ctx;
+       export_ctx.cbs = cbs;
        export_ctx.wimlib_err_code = 0;
        export_ctx.bytes_remaining = size;
 
@@ -852,6 +850,9 @@ winnt_scan_efsrpc_raw_data(struct wim_inode *inode, const wchar_t *nt_path,
        if (ret)
                goto err;
 
+       /* Empty EFSRPC data does not make sense  */
+       wimlib_assert(blob->size != 0);
+
        strm = inode_add_stream(inode, STREAM_TYPE_EFSRPC_RAW_DATA,
                                NO_STREAM_NAME, blob);
        if (!strm)
@@ -1099,6 +1100,37 @@ out_free_buf:
        return ret;
 }
 
+static u64
+get_sort_key(HANDLE h)
+{
+       STARTING_VCN_INPUT_BUFFER in = { .StartingVcn.QuadPart = 0 };
+       RETRIEVAL_POINTERS_BUFFER out;
+       DWORD bytesReturned;
+
+       if (!DeviceIoControl(h, FSCTL_GET_RETRIEVAL_POINTERS,
+                            &in, sizeof(in),
+                            &out, sizeof(out),
+                            &bytesReturned, NULL))
+               return 0;
+
+       if (out.ExtentCount < 1)
+               return 0;
+
+       return out.Extents[0].Lcn.QuadPart;
+}
+
+static void
+set_sort_key(struct wim_inode *inode, u64 sort_key)
+{
+       for (unsigned i = 0; i < inode->i_num_streams; i++) {
+               struct wim_inode_stream *strm = &inode->i_streams[i];
+               struct blob_descriptor *blob = stream_blob_resolved(strm);
+               if (blob && (blob->blob_location == BLOB_IN_WINNT_FILE_ON_DISK ||
+                            blob->blob_location == BLOB_WIN32_ENCRYPTED))
+                       blob->sort_key = sort_key;
+       }
+}
+
 static int
 winnt_build_dentry_tree_recursive(struct wim_dentry **root_ret,
                                  HANDLE cur_dir,
@@ -1117,6 +1149,7 @@ winnt_build_dentry_tree_recursive(struct wim_dentry **root_ret,
        NTSTATUS status;
        FILE_ALL_INFORMATION file_info;
        ACCESS_MASK requestedPerms;
+       u64 sort_key;
 
        ret = try_exclude(full_path, full_path_nchars, params);
        if (ret < 0) /* Excluded? */
@@ -1341,6 +1374,8 @@ retry_open:
                }
        }
 
+       sort_key = get_sort_key(h);
+
        if (unlikely(inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED)) {
                /* Load information about the raw encrypted data.  This is
                 * needed for any directory or non-directory that has
@@ -1378,6 +1413,8 @@ retry_open:
                        goto out;
        }
 
+       set_sort_key(inode, sort_key);
+
        if (inode_is_directory(inode)) {
 
                /* Directory: recurse to children.  */