+struct win32_encrypted_extract_ctx {
+ void *file_ctx;
+ int wimlib_err_code;
+ bool done;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ u8 buf[WIM_CHUNK_SIZE];
+ size_t buf_filled;
+};
+
+static DWORD WINAPI
+win32_encrypted_import_cb(unsigned char *data, void *_ctx,
+ unsigned long *len_p)
+{
+ struct win32_encrypted_extract_ctx *ctx = _ctx;
+ unsigned long len = *len_p;
+
+ pthread_mutex_lock(&ctx->mutex);
+ while (len) {
+ size_t bytes_to_copy;
+
+ DEBUG("Importing up to %lu more bytes of raw encrypted data", len);
+ while (ctx->buf_filled == 0) {
+ if (ctx->done)
+ goto out;
+ pthread_cond_wait(&ctx->cond, &ctx->mutex);
+ }
+ bytes_to_copy = min(len, ctx->buf_filled);
+ memcpy(data, ctx->buf, bytes_to_copy);
+ len -= bytes_to_copy;
+ data += bytes_to_copy;
+ ctx->buf_filled -= bytes_to_copy;
+ memmove(ctx->buf, ctx->buf + bytes_to_copy, ctx->buf_filled);
+ pthread_cond_signal(&ctx->cond);
+ }
+out:
+ *len_p -= len;
+ pthread_mutex_unlock(&ctx->mutex);
+ return ERROR_SUCCESS;
+}
+
+static void *
+win32_encrypted_import_proc(void *arg)
+{
+ struct win32_encrypted_extract_ctx *ctx = arg;
+ DWORD ret;
+ ret = WriteEncryptedFileRaw(win32_encrypted_import_cb, ctx,
+ ctx->file_ctx);
+ pthread_mutex_lock(&ctx->mutex);
+ if (ret == ERROR_SUCCESS)
+ ctx->wimlib_err_code = 0;
+ else {
+ win32_error(ret);
+ ctx->wimlib_err_code = WIMLIB_ERR_WRITE;
+ }
+ ctx->done = true;
+ pthread_mutex_unlock(&ctx->mutex);
+ return NULL;
+}
+
+
+static int
+win32_extract_raw_encrypted_chunk(const void *buf, size_t len, void *arg)
+{
+ struct win32_encrypted_extract_ctx *ctx = arg;
+ size_t bytes_to_copy;
+
+ while (len) {
+ DEBUG("Extracting up to %zu more bytes of encrypted data", len);
+ pthread_mutex_lock(&ctx->mutex);
+ while (!ctx->done && ctx->buf_filled == WIM_CHUNK_SIZE)
+ pthread_cond_wait(&ctx->cond, &ctx->mutex);
+ if (ctx->done) {
+ pthread_mutex_unlock(&ctx->mutex);
+ return ctx->wimlib_err_code;
+ }
+ bytes_to_copy = min(len, WIM_CHUNK_SIZE - ctx->buf_filled);
+ memcpy(&ctx->buf[ctx->buf_filled], buf, bytes_to_copy);
+ len -= bytes_to_copy;
+ buf += bytes_to_copy;
+ ctx->buf_filled += bytes_to_copy;
+ pthread_cond_signal(&ctx->cond);
+ pthread_mutex_unlock(&ctx->mutex);
+ }
+ return 0;
+}
+