Wine-Devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2021
- 70 participants
- 697 discussions
[PATCH vkd3d v3 1/6] vkd3d-shader: Rename HLSL_IR_ASSIGNMENT to HLSL_IR_STORE.
by Zebediah Figura April 13, 2021
by Zebediah Figura April 13, 2021
April 13, 2021
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/hlsl.c | 76 ++++++++++++++++----------------
libs/vkd3d-shader/hlsl.h | 22 ++++-----
libs/vkd3d-shader/hlsl.y | 50 ++++++++++-----------
libs/vkd3d-shader/hlsl_codegen.c | 59 ++++++++++++-------------
4 files changed, 103 insertions(+), 104 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 53b9db36..23003f44 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -418,28 +418,28 @@ static bool type_is_single_reg(const struct hlsl_type *type)
return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;
}
-struct hlsl_ir_assignment *hlsl_new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
+struct hlsl_ir_store *hlsl_new_store(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc)
{
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
if (!writemask && type_is_single_reg(rhs->data_type))
writemask = (1 << rhs->data_type->dimx) - 1;
- if (!(assign = vkd3d_malloc(sizeof(*assign))))
+ if (!(store = vkd3d_malloc(sizeof(*store))))
return NULL;
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc);
- assign->lhs.var = var;
- hlsl_src_from_node(&assign->lhs.offset, offset);
- hlsl_src_from_node(&assign->rhs, rhs);
- assign->writemask = writemask;
- return assign;
+ init_node(&store->node, HLSL_IR_STORE, NULL, loc);
+ store->lhs.var = var;
+ hlsl_src_from_node(&store->lhs.offset, offset);
+ hlsl_src_from_node(&store->rhs, rhs);
+ store->writemask = writemask;
+ return store;
}
-struct hlsl_ir_assignment *hlsl_new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
+struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
{
- return hlsl_new_assignment(lhs, NULL, rhs, 0, rhs->loc);
+ return hlsl_new_store(lhs, NULL, rhs, 0, rhs->loc);
}
struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n,
@@ -830,13 +830,13 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
{
static const char * const names[] =
{
- "HLSL_IR_ASSIGNMENT",
"HLSL_IR_CONSTANT",
"HLSL_IR_EXPR",
"HLSL_IR_IF",
"HLSL_IR_LOAD",
"HLSL_IR_LOOP",
"HLSL_IR_JUMP",
+ "HLSL_IR_STORE",
"HLSL_IR_SWIZZLE",
};
@@ -909,17 +909,6 @@ static const char *debug_writemask(DWORD writemask)
return vkd3d_dbg_sprintf(".%s", string);
}
-static void dump_ir_assignment(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_assignment *assign)
-{
- vkd3d_string_buffer_printf(buffer, "= (");
- dump_deref(buffer, &assign->lhs);
- if (assign->writemask != VKD3DSP_WRITEMASK_ALL)
- vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(assign->writemask));
- vkd3d_string_buffer_printf(buffer, " ");
- dump_src(buffer, &assign->rhs);
- vkd3d_string_buffer_printf(buffer, ")");
-}
-
static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_constant *constant)
{
struct hlsl_type *type = constant->node.data_type;
@@ -1080,6 +1069,17 @@ static void dump_ir_loop(struct vkd3d_string_buffer *buffer, const struct hlsl_i
vkd3d_string_buffer_printf(buffer, "}\n");
}
+static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
+{
+ vkd3d_string_buffer_printf(buffer, "= (");
+ dump_deref(buffer, &store->lhs);
+ if (store->writemask != VKD3DSP_WRITEMASK_ALL)
+ vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(store->writemask));
+ vkd3d_string_buffer_printf(buffer, " ");
+ dump_src(buffer, &store->rhs);
+ vkd3d_string_buffer_printf(buffer, ")");
+}
+
static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_swizzle *swizzle)
{
unsigned int i;
@@ -1111,10 +1111,6 @@ static void dump_instr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_
switch (instr->type)
{
- case HLSL_IR_ASSIGNMENT:
- dump_ir_assignment(buffer, hlsl_ir_assignment(instr));
- break;
-
case HLSL_IR_CONSTANT:
dump_ir_constant(buffer, hlsl_ir_constant(instr));
break;
@@ -1139,6 +1135,10 @@ static void dump_instr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_
dump_ir_loop(buffer, hlsl_ir_loop(instr));
break;
+ case HLSL_IR_STORE:
+ dump_ir_store(buffer, hlsl_ir_store(instr));
+ break;
+
case HLSL_IR_SWIZZLE:
dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr));
break;
@@ -1198,13 +1198,6 @@ void hlsl_free_instr_list(struct list *list)
vkd3d_free(list);
}
-static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
-{
- hlsl_src_remove(&assignment->rhs);
- hlsl_src_remove(&assignment->lhs.offset);
- vkd3d_free(assignment);
-}
-
static void free_ir_constant(struct hlsl_ir_constant *constant)
{
vkd3d_free(constant);
@@ -1251,6 +1244,13 @@ static void free_ir_loop(struct hlsl_ir_loop *loop)
vkd3d_free(loop);
}
+static void free_ir_store(struct hlsl_ir_store *store)
+{
+ hlsl_src_remove(&store->rhs);
+ hlsl_src_remove(&store->lhs.offset);
+ vkd3d_free(store);
+}
+
static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
{
hlsl_src_remove(&swizzle->val);
@@ -1261,10 +1261,6 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
{
switch (node->type)
{
- case HLSL_IR_ASSIGNMENT:
- free_ir_assignment(hlsl_ir_assignment(node));
- break;
-
case HLSL_IR_CONSTANT:
free_ir_constant(hlsl_ir_constant(node));
break;
@@ -1289,6 +1285,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
free_ir_loop(hlsl_ir_loop(node));
break;
+ case HLSL_IR_STORE:
+ free_ir_store(hlsl_ir_store(node));
+ break;
+
case HLSL_IR_SWIZZLE:
free_ir_swizzle(hlsl_ir_swizzle(node));
break;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index cf12f63f..c82cd4f5 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -139,13 +139,13 @@ struct hlsl_struct_field
enum hlsl_ir_node_type
{
- HLSL_IR_ASSIGNMENT = 0,
HLSL_IR_CONSTANT,
HLSL_IR_EXPR,
HLSL_IR_IF,
HLSL_IR_LOAD,
HLSL_IR_LOOP,
HLSL_IR_JUMP,
+ HLSL_IR_STORE,
HLSL_IR_SWIZZLE,
};
@@ -352,7 +352,7 @@ struct hlsl_ir_load
struct hlsl_deref src;
};
-struct hlsl_ir_assignment
+struct hlsl_ir_store
{
struct hlsl_ir_node node;
struct hlsl_deref lhs;
@@ -420,12 +420,6 @@ enum hlsl_error_level
HLSL_LEVEL_NOTE,
};
-static inline struct hlsl_ir_assignment *hlsl_ir_assignment(const struct hlsl_ir_node *node)
-{
- assert(node->type == HLSL_IR_ASSIGNMENT);
- return CONTAINING_RECORD(node, struct hlsl_ir_assignment, node);
-}
-
static inline struct hlsl_ir_constant *hlsl_ir_constant(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_CONSTANT);
@@ -462,6 +456,12 @@ static inline struct hlsl_ir_loop *hlsl_ir_loop(const struct hlsl_ir_node *node)
return CONTAINING_RECORD(node, struct hlsl_ir_loop, node);
}
+static inline struct hlsl_ir_store *hlsl_ir_store(const struct hlsl_ir_node *node)
+{
+ assert(node->type == HLSL_IR_STORE);
+ return CONTAINING_RECORD(node, struct hlsl_ir_store, node);
+}
+
static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_SWIZZLE);
@@ -520,8 +520,6 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) DEC
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
unsigned int array_size) DECLSPEC_HIDDEN;
-struct hlsl_ir_assignment *hlsl_new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
- struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
struct hlsl_ir_node *hlsl_new_binary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1,
struct hlsl_ir_node *arg2) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
@@ -534,8 +532,10 @@ struct hlsl_ir_jump *hlsl_new_jump(enum hlsl_ir_jump_type type, struct vkd3d_sha
struct hlsl_ir_load *hlsl_new_load(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type,
struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
struct hlsl_ir_loop *hlsl_new_loop(struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
-struct hlsl_ir_assignment *hlsl_new_simple_assignment(struct hlsl_ir_var *lhs,
+struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ir_var *lhs,
struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN;
+struct hlsl_ir_store *hlsl_new_store(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
+ struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields) DECLSPEC_HIDDEN;
struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
struct hlsl_ir_node *val, struct vkd3d_shader_location *loc) DECLSPEC_HIDDEN;
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index ab7059d3..6216b100 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -499,14 +499,14 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs
if (return_value)
{
- struct hlsl_ir_assignment *assignment;
+ struct hlsl_ir_store *store;
if (!(return_value = add_implicit_conversion(ctx, instrs, return_value, return_type, &loc)))
return NULL;
- if (!(assignment = hlsl_new_simple_assignment(ctx->cur_function->return_var, return_value)))
+ if (!(store = hlsl_new_simple_store(ctx->cur_function->return_var, return_value)))
return NULL;
- list_add_after(&return_value->entry, &assignment->node.entry);
+ list_add_after(&return_value->entry, &store->node.entry);
}
else if (!hlsl_type_is_void(return_type))
{
@@ -543,17 +543,17 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs,
}
else
{
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
char name[27];
sprintf(name, "<deref-%p>", var_node);
if (!(var = hlsl_new_synthetic_var(ctx, name, var_node->data_type, var_node->loc)))
return NULL;
- if (!(assign = hlsl_new_simple_assignment(var, var_node)))
+ if (!(store = hlsl_new_simple_store(var, var_node)))
return NULL;
- list_add_tail(instrs, &assign->node.entry);
+ list_add_tail(instrs, &store->node.entry);
}
if (!(load = hlsl_new_load(var, offset, data_type, loc)))
@@ -900,7 +900,7 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type));
return 0;
- case HLSL_IR_ASSIGNMENT:
+ case HLSL_IR_STORE:
default:
WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type));
return 0;
@@ -1216,7 +1216,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
{
struct hlsl_type *lhs_type = lhs->data_type;
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
struct hlsl_ir_expr *copy;
DWORD writemask = 0;
@@ -1239,7 +1239,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
return NULL;
}
- if (!(assign = vkd3d_malloc(sizeof(*assign))))
+ if (!(store = vkd3d_malloc(sizeof(*store))))
return NULL;
while (lhs->type != HLSL_IR_LOAD)
@@ -1247,7 +1247,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_IR_UNOP_CAST)
{
FIXME("Cast on the lhs.\n");
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
else if (lhs->type == HLSL_IR_SWIZZLE)
@@ -1261,13 +1261,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (!invert_swizzle(&s, &writemask, &width))
{
hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
{
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
list_add_tail(instrs, &new_swizzle->node.entry);
@@ -1278,17 +1278,17 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
else
{
hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue.");
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
}
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, lhs->loc);
- assign->writemask = writemask;
- assign->lhs.var = hlsl_ir_load(lhs)->src.var;
- hlsl_src_from_node(&assign->lhs.offset, hlsl_ir_load(lhs)->src.offset.node);
- hlsl_src_from_node(&assign->rhs, rhs);
- list_add_tail(instrs, &assign->node.entry);
+ init_node(&store->node, HLSL_IR_STORE, NULL, lhs->loc);
+ store->writemask = writemask;
+ store->lhs.var = hlsl_ir_load(lhs)->src.var;
+ hlsl_src_from_node(&store->lhs.offset, hlsl_ir_load(lhs)->src.offset.node);
+ hlsl_src_from_node(&store->rhs, rhs);
+ list_add_tail(instrs, &store->node.entry);
/* Don't use the instruction itself as a source, as this makes structure
* splitting easier. Instead copy it here. Since we retrieve sources from
@@ -1355,7 +1355,7 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru
LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
{
struct hlsl_ir_node *node = initializer->args[i];
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
struct hlsl_ir_constant *c;
if (i++ >= initializer->args_count)
@@ -1367,9 +1367,9 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru
break;
list_add_tail(list, &c->node.entry);
- if (!(assign = hlsl_new_assignment(var, &c->node, node, 0, node->loc)))
+ if (!(store = hlsl_new_store(var, &c->node, node, 0, node->loc)))
break;
- list_add_tail(list, &assign->node.entry);
+ list_add_tail(list, &store->node.entry);
}
else
FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
@@ -2724,8 +2724,8 @@ postfix_expr:
/* var_modifiers is necessary to avoid shift/reduce conflicts. */
| var_modifiers type '(' initializer_expr_list ')'
{
- struct hlsl_ir_assignment *assignment;
unsigned int i, writemask_offset = 0;
+ struct hlsl_ir_store *store;
static unsigned int counter;
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
@@ -2788,11 +2788,11 @@ postfix_expr:
ctx->builtin_types.vector[$2->base_type][width - 1], &arg->loc)))
continue;
- if (!(assignment = hlsl_new_assignment(var, NULL, arg,
+ if (!(store = hlsl_new_store(var, NULL, arg,
((1 << width) - 1) << writemask_offset, arg->loc)))
YYABORT;
writemask_offset += width;
- list_add_tail($4.instrs, &assignment->node.entry);
+ list_add_tail($4.instrs, &store->node.entry);
}
vkd3d_free($4.args);
if (!(load = hlsl_new_var_load(var, @2)))
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index dbd591af..0641aa0f 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -27,8 +27,8 @@
static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var)
{
struct vkd3d_string_buffer *name;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_var *const_var;
+ struct hlsl_ir_store *store;
struct hlsl_ir_load *load;
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers)))
@@ -55,7 +55,7 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru
}
list_add_head(instrs, &load->node.entry);
- if (!(store = hlsl_new_simple_assignment(var, &load->node)))
+ if (!(store = hlsl_new_simple_store(var, &load->node)))
{
ctx->failed = true;
return;
@@ -67,8 +67,8 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
struct hlsl_type *type, unsigned int field_offset, const char *semantic)
{
struct vkd3d_string_buffer *name;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_constant *offset;
+ struct hlsl_ir_store *store;
struct hlsl_ir_var *varying;
struct hlsl_ir_load *load;
@@ -102,7 +102,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
}
list_add_after(&load->node.entry, &offset->node.entry);
- if (!(store = hlsl_new_assignment(var, &offset->node, &load->node, 0, var->loc)))
+ if (!(store = hlsl_new_store(var, &offset->node, &load->node, 0, var->loc)))
{
ctx->failed = true;
return;
@@ -144,8 +144,8 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
struct hlsl_type *type, unsigned int field_offset, const char *semantic)
{
struct vkd3d_string_buffer *name;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_constant *offset;
+ struct hlsl_ir_store *store;
struct hlsl_ir_var *varying;
struct hlsl_ir_load *load;
@@ -179,7 +179,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
}
list_add_after(&offset->node.entry, &load->node.entry);
- if (!(store = hlsl_new_assignment(varying, NULL, &load->node, 0, var->loc)))
+ if (!(store = hlsl_new_store(varying, NULL, &load->node, 0, var->loc)))
{
ctx->failed = true;
return;
@@ -285,15 +285,15 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
{
const struct hlsl_struct_field *field;
const struct hlsl_ir_load *rhs_load;
- struct hlsl_ir_assignment *assign;
const struct hlsl_ir_node *rhs;
const struct hlsl_type *type;
+ struct hlsl_ir_store *store;
- if (instr->type != HLSL_IR_ASSIGNMENT)
+ if (instr->type != HLSL_IR_STORE)
return false;
- assign = hlsl_ir_assignment(instr);
- rhs = assign->rhs.node;
+ store = hlsl_ir_store(instr);
+ rhs = store->rhs.node;
type = rhs->data_type;
if (type->type != HLSL_CLASS_STRUCT)
return false;
@@ -302,8 +302,8 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
{
+ struct hlsl_ir_store *field_store;
struct hlsl_ir_node *offset, *add;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_load *field_load;
struct hlsl_ir_constant *c;
@@ -333,9 +333,9 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
list_add_before(&instr->entry, &field_load->node.entry);
offset = &c->node;
- if (assign->lhs.offset.node)
+ if (store->lhs.offset.node)
{
- if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, assign->lhs.offset.node, &c->node)))
+ if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, store->lhs.offset.node, &c->node)))
{
ctx->failed = true;
return false;
@@ -344,20 +344,19 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
offset = add;
}
- if (!(store = hlsl_new_assignment(assign->lhs.var, offset, &field_load->node, 0, instr->loc)))
+ if (!(field_store = hlsl_new_store(store->lhs.var, offset, &field_load->node, 0, instr->loc)))
{
ctx->failed = true;
return false;
}
- list_add_before(&instr->entry, &store->node.entry);
+ list_add_before(&instr->entry, &field_store->node.entry);
}
- /* Remove the assignment instruction, so that we can split structs
- * which contain other structs. Although assignment instructions
- * produce a value, we don't allow HLSL_IR_ASSIGNMENT to be used as
- * a source. */
- list_remove(&assign->node.entry);
- hlsl_free_instr(&assign->node);
+ /* Remove the store instruction, so that we can split structs which contain
+ * other structs. Although assignments produce a value, we don't allow
+ * HLSL_IR_STORE to be used as a source. */
+ list_remove(&store->node.entry);
+ hlsl_free_instr(&store->node);
return true;
}
@@ -440,10 +439,10 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
}
break;
- case HLSL_IR_ASSIGNMENT:
+ case HLSL_IR_STORE:
{
- struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr);
- struct hlsl_ir_var *var = assignment->lhs.var;
+ struct hlsl_ir_store *store = hlsl_ir_store(instr);
+ struct hlsl_ir_var *var = store->lhs.var;
if (var->last_read < instr->index)
{
@@ -517,16 +516,16 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
{
switch (instr->type)
{
- case HLSL_IR_ASSIGNMENT:
+ case HLSL_IR_STORE:
{
- struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr);
+ struct hlsl_ir_store *store = hlsl_ir_store(instr);
- var = assignment->lhs.var;
+ var = store->lhs.var;
if (!var->first_write)
var->first_write = loop_first ? min(instr->index, loop_first) : instr->index;
- assignment->rhs.node->last_read = instr->index;
- if (assignment->lhs.offset.node)
- assignment->lhs.offset.node->last_read = instr->index;
+ store->rhs.node->last_read = instr->index;
+ if (store->lhs.offset.node)
+ store->lhs.offset.node->last_read = instr->index;
break;
}
case HLSL_IR_EXPR:
--
2.31.1
5
20
[PATCH] kernel32/tests: Add a test for special characters in pipe names.
by Zebediah Figura April 13, 2021
by Zebediah Figura April 13, 2021
April 13, 2021
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=28995
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/kernel32/tests/pipe.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index 0ac356c8483..1ed4ecec7e6 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -673,6 +673,14 @@ static void test_CreateNamedPipe(int pipemode)
CloseHandle(hnp);
+ hnp = CreateNamedPipeA("\\\\.\\pipe\\a<>*?|\"/b", PIPE_ACCESS_DUPLEX,
+ PIPE_TYPE_BYTE, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
+ ok(hnp != INVALID_HANDLE_VALUE, "failed to create pipe, error %u\n", GetLastError());
+ hFile = CreateFileA("\\\\.\\pipe\\a<>*?|\"/b", 0, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok(hFile != INVALID_HANDLE_VALUE, "failed to open pipe, error %u\n", GetLastError());
+ CloseHandle(hFile);
+ CloseHandle(hnp);
+
if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n");
}
--
2.30.2
1
0
April 13, 2021
The Vulkan spec says:
The queueFamilyIndex member of each element of pQueueCreateInfos must be unique
within pQueueCreateInfos, except that two members can share the same
queueFamilyIndex if one is a protected-capable queue and one is not a
protected-capable queue.
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/vulkan.c | 84 ++++++++++++++++++--------------
dlls/winevulkan/vulkan_private.h | 6 ++-
2 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 45beea97240..1a3da60d664 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -316,25 +316,21 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device,
}
}
-static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
- uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags)
+static void wine_vk_device_get_queues(struct VkDevice_T *device,
+ uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags,
+ struct VkQueue_T* queues)
{
VkDeviceQueueInfo2 queue_info;
- struct VkQueue_T *queues;
unsigned int i;
- if (!(queues = calloc(queue_count, sizeof(*queues))))
- {
- ERR("Failed to allocate memory for queues\n");
- return NULL;
- }
-
for (i = 0; i < queue_count; i++)
{
struct VkQueue_T *queue = &queues[i];
queue->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
queue->device = device;
+ queue->family_index = family_index;
+ queue->queue_index = i;
queue->flags = flags;
/* The Vulkan spec says:
@@ -358,8 +354,6 @@ static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, queue, queue->queue);
}
-
- return queues;
}
static void wine_vk_device_free_create_info(VkDeviceCreateInfo *create_info)
@@ -431,17 +425,19 @@ static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src
*/
static void wine_vk_device_free(struct VkDevice_T *device)
{
+ struct VkQueue_T *queue;
+
if (!device)
return;
if (device->queues)
{
unsigned int i;
- for (i = 0; i < device->max_queue_families; i++)
+ for (i = 0; i < device->queue_count; i++)
{
- if (device->queues[i] && device->queues[i]->queue)
- WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, device->queues[i]);
- free(device->queues[i]);
+ queue = &device->queues[i];
+ if (queue && queue->queue)
+ WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, queue);
}
free(device->queues);
device->queues = NULL;
@@ -758,7 +754,7 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
const VkAllocationCallbacks *allocator, VkDevice *device)
{
VkDeviceCreateInfo create_info_host;
- uint32_t max_queue_families;
+ struct VkQueue_T *next_queue;
struct VkDevice_T *object;
unsigned int i;
VkResult res;
@@ -813,17 +809,18 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
/* We need to cache all queues within the device as each requires wrapping since queues are
* dispatchable objects.
*/
- phys_dev->instance->funcs.p_vkGetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev,
- &max_queue_families, NULL);
- object->max_queue_families = max_queue_families;
- TRACE("Max queue families: %u.\n", object->max_queue_families);
+ for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
+ {
+ object->queue_count += create_info_host.pQueueCreateInfos[i].queueCount;
+ }
- if (!(object->queues = calloc(max_queue_families, sizeof(*object->queues))))
+ if (!(object->queues = calloc(object->queue_count, sizeof(*object->queues))))
{
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto fail;
}
+ next_queue = object->queues;
for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
{
uint32_t flags = create_info_host.pQueueCreateInfos[i].flags;
@@ -832,12 +829,8 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
TRACE("Queue family index %u, queue count %u.\n", family_index, queue_count);
- if (!(object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index, queue_count, flags)))
- {
- ERR("Failed to allocate memory for queues.\n");
- res = VK_ERROR_OUT_OF_HOST_MEMORY;
- goto fail;
- }
+ wine_vk_device_get_queues(object, family_index, queue_count, flags, next_queue);
+ next_queue += queue_count;
}
object->quirks = phys_dev->instance->quirks;
@@ -1118,17 +1111,42 @@ void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool_handle
wine_vk_free_command_buffers(device, pool, count, buffers);
}
+static VkQueue wine_vk_device_find_queue(VkDevice device, const VkDeviceQueueInfo2 *info)
+{
+ struct VkQueue_T* queue;
+ uint32_t i;
+
+ for (i = 0; i < device->queue_count; i++)
+ {
+ queue = &device->queues[i];
+ if (queue->family_index == info->queueFamilyIndex
+ && queue->queue_index == info->queueIndex
+ && queue->flags == info->flags)
+ {
+ return queue;
+ }
+ }
+
+ return VK_NULL_HANDLE;
+}
+
void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t family_index,
uint32_t queue_index, VkQueue *queue)
{
+ VkDeviceQueueInfo2 queue_info;
TRACE("%p, %u, %u, %p\n", device, family_index, queue_index, queue);
- *queue = &device->queues[family_index][queue_index];
+ queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
+ queue_info.pNext = NULL;
+ queue_info.flags = 0;
+ queue_info.queueFamilyIndex = family_index;
+ queue_info.queueIndex = queue_index;
+
+ *queue = wine_vk_device_find_queue(device, &queue_info);
}
void WINAPI wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *info, VkQueue *queue)
{
- struct VkQueue_T *matching_queue;
const VkBaseInStructure *chain;
TRACE("%p, %p, %p\n", device, info, queue);
@@ -1136,13 +1154,7 @@ void WINAPI wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *in
if ((chain = info->pNext))
FIXME("Ignoring a linked structure of type %u.\n", chain->sType);
- matching_queue = &device->queues[info->queueFamilyIndex][info->queueIndex];
- if (matching_queue->flags != info->flags)
- {
- WARN("No matching flags were specified %#x, %#x.\n", matching_queue->flags, info->flags);
- matching_queue = VK_NULL_HANDLE;
- }
- *queue = matching_queue;
+ *queue = wine_vk_device_find_queue(device, info);
}
VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t count,
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 6574d282eea..5b0494334cd 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -89,8 +89,8 @@ struct VkDevice_T
struct VkPhysicalDevice_T *phys_dev; /* parent */
VkDevice device; /* native device */
- struct VkQueue_T **queues;
- uint32_t max_queue_families;
+ struct VkQueue_T* queues;
+ uint32_t queue_count;
unsigned int quirks;
@@ -155,6 +155,8 @@ struct VkQueue_T
struct VkDevice_T *device; /* parent */
VkQueue queue; /* native queue */
+ uint32_t family_index;
+ uint32_t queue_index;
VkDeviceQueueCreateFlags flags;
struct wine_vk_mapping mapping;
--
2.31.1
1
0
[PATCH 3/3] windows.media.devices: Stub DefaultAudio{Capture,Render}DeviceChanged events
by Andrew Eikum April 13, 2021
by Andrew Eikum April 13, 2021
April 13, 2021
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/windows.media.devices/main.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/windows.media.devices/main.c b/dlls/windows.media.devices/main.c
index 8d4c63f329a..1254ab87816 100644
--- a/dlls/windows.media.devices/main.c
+++ b/dlls/windows.media.devices/main.c
@@ -309,7 +309,10 @@ static HRESULT WINAPI media_device_statics_add_DefaultAudioCaptureDeviceChanged(
EventRegistrationToken *token)
{
FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
- return E_NOTIMPL;
+ if(!token)
+ return E_POINTER;
+ token->value = 1;
+ return S_OK;
}
static HRESULT WINAPI media_device_statics_remove_DefaultAudioCaptureDeviceChanged(
@@ -317,7 +320,7 @@ static HRESULT WINAPI media_device_statics_remove_DefaultAudioCaptureDeviceChang
EventRegistrationToken token)
{
FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
- return E_NOTIMPL;
+ return S_OK;
}
static HRESULT WINAPI media_device_statics_add_DefaultAudioRenderDeviceChanged(
@@ -326,7 +329,10 @@ static HRESULT WINAPI media_device_statics_add_DefaultAudioRenderDeviceChanged(
EventRegistrationToken *token)
{
FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
- return E_NOTIMPL;
+ if(!token)
+ return E_POINTER;
+ token->value = 1;
+ return S_OK;
}
static HRESULT WINAPI media_device_statics_remove_DefaultAudioRenderDeviceChanged(
@@ -334,7 +340,7 @@ static HRESULT WINAPI media_device_statics_remove_DefaultAudioRenderDeviceChange
EventRegistrationToken token)
{
FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
- return E_NOTIMPL;
+ return S_OK;
}
static IMediaDeviceStaticsVtbl media_device_statics_vtbl = {
--
2.31.1
1
0
[PATCH 2/3] windows.media.devices: Implement IMediaDeviceStatics::GetDefaultAudio{Capture,Render}Id
by Andrew Eikum April 13, 2021
by Andrew Eikum April 13, 2021
April 13, 2021
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/windows.media.devices/main.c | 85 +++++++-
dlls/windows.media.devices/tests/devices.c | 223 ++++++++++++++++++++-
2 files changed, 303 insertions(+), 5 deletions(-)
diff --git a/dlls/windows.media.devices/main.c b/dlls/windows.media.devices/main.c
index 9797644d71a..8d4c63f329a 100644
--- a/dlls/windows.media.devices/main.c
+++ b/dlls/windows.media.devices/main.c
@@ -25,9 +25,11 @@
#include "winbase.h"
#include "winstring.h"
#include "wine/debug.h"
+#include "wine/heap.h"
#include "objbase.h"
#include "activation.h"
+#include "mmdeviceapi.h"
#define WIDL_using_Windows_Foundation
#define WIDL_using_Windows_Foundation_Collections
@@ -46,6 +48,16 @@ static const char *debugstr_hstring(HSTRING hstr)
return wine_dbgstr_wn(str, len);
}
+static ERole AudioDeviceRole_to_ERole(AudioDeviceRole role)
+{
+ switch(role){
+ case AudioDeviceRole_Communications:
+ return eCommunications;
+ default:
+ return eMultimedia;
+ }
+}
+
struct windows_media_devices
{
IActivationFactory IActivationFactory_iface;
@@ -151,6 +163,71 @@ static const struct IActivationFactoryVtbl activation_factory_vtbl =
windows_media_devices_ActivateInstance,
};
+static HRESULT get_default_device_id(EDataFlow direction, AudioDeviceRole role, HSTRING *device_id_hstr)
+{
+ HRESULT hr;
+ WCHAR *devid, *s;
+ IMMDevice *dev;
+ IMMDeviceEnumerator *devenum;
+ ERole mmdev_role = AudioDeviceRole_to_ERole(role);
+
+ static const WCHAR id_fmt_pre[] = L"\\\\?\\SWD#MMDEVAPI#";
+ static const WCHAR id_fmt_hash[] = L"#";
+ static const size_t GUID_STR_LEN = 38; /* == strlen("{00000000-0000-0000-0000-000000000000}") */
+
+ *device_id_hstr = NULL;
+
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create MMDeviceEnumerator: %08x\n", hr);
+ return hr;
+ }
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, direction, mmdev_role, &dev);
+ if (FAILED(hr))
+ {
+ WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
+ IMMDeviceEnumerator_Release(devenum);
+ return hr;
+ }
+
+ hr = IMMDevice_GetId(dev, &devid);
+ if (FAILED(hr))
+ {
+ WARN("GetId failed: %08x\n", hr);
+ IMMDevice_Release(dev);
+ IMMDeviceEnumerator_Release(devenum);
+ return hr;
+ }
+
+ s = heap_alloc((sizeof(id_fmt_pre) - sizeof(WCHAR)) +
+ (sizeof(id_fmt_hash) - sizeof(WCHAR)) +
+ (wcslen(devid) + GUID_STR_LEN + 1 /* nul */) * sizeof(WCHAR));
+
+ wcscpy(s, id_fmt_pre);
+ wcscat(s, devid);
+ wcscat(s, id_fmt_hash);
+
+ if(direction == eRender)
+ StringFromGUID2(&DEVINTERFACE_AUDIO_RENDER, s + wcslen(s), GUID_STR_LEN + 1);
+ else
+ StringFromGUID2(&DEVINTERFACE_AUDIO_CAPTURE, s + wcslen(s), GUID_STR_LEN + 1);
+
+ hr = WindowsCreateString(s, wcslen(s), device_id_hstr);
+ if (FAILED(hr))
+ WARN("WindowsCreateString failed: %08x\n", hr);
+
+ heap_free(s);
+
+ CoTaskMemFree(devid);
+ IMMDevice_Release(dev);
+ IMMDeviceEnumerator_Release(devenum);
+
+ return hr;
+}
+
static HRESULT WINAPI media_device_statics_QueryInterface(IMediaDeviceStatics *iface,
REFIID riid, void **ppvObject)
{
@@ -215,15 +292,15 @@ static HRESULT WINAPI media_device_statics_GetVideoCaptureSelector(IMediaDeviceS
static HRESULT WINAPI media_device_statics_GetDefaultAudioCaptureId(IMediaDeviceStatics *iface,
AudioDeviceRole role, HSTRING *value)
{
- FIXME("iface %p, role 0x%x, value %p stub!\n", iface, role, value);
- return E_NOTIMPL;
+ TRACE("iface %p, role 0x%x, value %p\n", iface, role, value);
+ return get_default_device_id(eCapture, role, value);
}
static HRESULT WINAPI media_device_statics_GetDefaultAudioRenderId(IMediaDeviceStatics *iface,
AudioDeviceRole role, HSTRING *value)
{
- FIXME("iface %p, role 0x%x, value %p stub!\n", iface, role, value);
- return E_NOTIMPL;
+ TRACE("iface %p, role 0x%x, value %p\n", iface, role, value);
+ return get_default_device_id(eRender, role, value);
}
static HRESULT WINAPI media_device_statics_add_DefaultAudioCaptureDeviceChanged(
diff --git a/dlls/windows.media.devices/tests/devices.c b/dlls/windows.media.devices/tests/devices.c
index 9c3019de773..f3777944848 100644
--- a/dlls/windows.media.devices/tests/devices.c
+++ b/dlls/windows.media.devices/tests/devices.c
@@ -42,6 +42,90 @@ static HRESULT (WINAPI *pRoInitialize)(RO_INIT_TYPE);
static void (WINAPI *pRoUninitialize)(void);
static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *);
static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING);
+static WCHAR *(WINAPI *pWindowsGetStringRawBuffer)(HSTRING, UINT32 *);
+
+static HRESULT (WINAPI *pActivateAudioInterfaceAsync)(const WCHAR *path,
+ REFIID riid, PROPVARIANT *params,
+ IActivateAudioInterfaceCompletionHandler *done_handler,
+ IActivateAudioInterfaceAsyncOperation **op);
+
+static IMMDeviceEnumerator *g_mmdevenum;
+static WCHAR *g_default_capture_id, *g_default_render_id;
+
+static struct {
+ LONG ref;
+ HANDLE evt;
+ CRITICAL_SECTION lock;
+ IActivateAudioInterfaceAsyncOperation *op;
+ char msg_pfx[128];
+ IUnknown *result_iface;
+ HRESULT result_hr;
+} async_activate_test;
+
+static HRESULT WINAPI async_activate_QueryInterface(
+ IActivateAudioInterfaceCompletionHandler *iface,
+ REFIID riid,
+ void **ppvObject)
+{
+ if (IsEqualIID(riid, &IID_IUnknown) ||
+ IsEqualIID(riid, &IID_IAgileObject) ||
+ IsEqualIID(riid, &IID_IActivateAudioInterfaceCompletionHandler))
+ {
+ *ppvObject = iface;
+ IUnknown_AddRef((IUnknown*)*ppvObject);
+ return S_OK;
+ }
+
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI async_activate_AddRef(
+ IActivateAudioInterfaceCompletionHandler *iface)
+{
+ return InterlockedIncrement(&async_activate_test.ref);
+}
+
+static ULONG WINAPI async_activate_Release(
+ IActivateAudioInterfaceCompletionHandler *iface)
+{
+ ULONG ref = InterlockedDecrement(&async_activate_test.ref);
+ if (ref == 1)
+ SetEvent(async_activate_test.evt);
+ return ref;
+}
+
+static HRESULT WINAPI async_activate_ActivateCompleted(
+ IActivateAudioInterfaceCompletionHandler *iface,
+ IActivateAudioInterfaceAsyncOperation *op)
+{
+ HRESULT hr;
+
+ EnterCriticalSection(&async_activate_test.lock);
+ ok(op == async_activate_test.op,
+ "%s: Got different completion operation\n",
+ async_activate_test.msg_pfx);
+ LeaveCriticalSection(&async_activate_test.lock);
+
+ hr = IActivateAudioInterfaceAsyncOperation_GetActivateResult(op,
+ &async_activate_test.result_hr, &async_activate_test.result_iface);
+ ok(hr == S_OK,
+ "%s: GetActivateResult failed: %08x\n",
+ async_activate_test.msg_pfx, hr);
+
+ return S_OK;
+}
+
+static IActivateAudioInterfaceCompletionHandlerVtbl async_activate_vtbl = {
+ async_activate_QueryInterface,
+ async_activate_AddRef,
+ async_activate_Release,
+ async_activate_ActivateCompleted,
+};
+
+static IActivateAudioInterfaceCompletionHandler async_activate_done = {
+ &async_activate_vtbl
+};
static void test_MediaDeviceStatics(void)
{
@@ -51,8 +135,11 @@ static void test_MediaDeviceStatics(void)
IActivationFactory *factory = NULL;
IInspectable *inspectable = NULL, *tmp_inspectable = NULL;
IAgileObject *agile_object = NULL, *tmp_agile_object = NULL;
+ HANDLE done_evt = CreateEventW(NULL, FALSE, FALSE, NULL);
+ IMMDevice *mmdev;
HSTRING str;
HRESULT hr;
+ DWORD dr;
hr = pWindowsCreateString(media_device_statics_name, wcslen(media_device_statics_name), &str);
ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr);
@@ -85,13 +172,100 @@ static void test_MediaDeviceStatics(void)
IInspectable_Release(inspectable);
IActivationFactory_Release(factory);
+ InitializeCriticalSection(&async_activate_test.lock);
+
+ /* test default capture device creation */
+ hr = IMediaDeviceStatics_GetDefaultAudioCaptureId(media_device_statics, AudioDeviceRole_Default, &str);
+ ok(hr == S_OK, "GetDefaultAudioCaptureId failed: %08x\n", hr);
+ ok((!!g_default_capture_id) == (!!str),
+ "Presence of default capture device doesn't match expected state\n");
+
+ if (g_default_capture_id)
+ {
+ ok(wcsstr(pWindowsGetStringRawBuffer(str, NULL), g_default_capture_id) != NULL,
+ "Expected to find substring of default capture id in %s\n",
+ wine_dbgstr_w(pWindowsGetStringRawBuffer(str, NULL)));
+
+ /* returned id does not work in GetDevice... */
+ hr = IMMDeviceEnumerator_GetDevice(g_mmdevenum, pWindowsGetStringRawBuffer(str, NULL), &mmdev);
+ ok(hr == E_INVALIDARG, "GetDevice gave wrong error: %08x\n", hr);
+
+ /* ...but does work in ActivateAudioInterfaceAsync */
+ async_activate_test.ref = 1;
+ async_activate_test.evt = done_evt;
+ async_activate_test.op = NULL;
+ async_activate_test.result_iface = NULL;
+ async_activate_test.result_hr = 0;
+ strcpy(async_activate_test.msg_pfx, "capture_activate");
+
+ EnterCriticalSection(&async_activate_test.lock);
+ hr = pActivateAudioInterfaceAsync(pWindowsGetStringRawBuffer(str, NULL),
+ &IID_IAudioClient2, NULL, &async_activate_done, &async_activate_test.op);
+ ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08x\n", hr);
+ LeaveCriticalSection(&async_activate_test.lock);
+
+ IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
+
+ dr = WaitForSingleObject(async_activate_test.evt, 1000); /* wait for all refs other than our own to be released */
+ ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
+ ok(async_activate_test.result_hr == S_OK, "Got unexpected activation result: %08x\n", async_activate_test.result_hr);
+ ok(async_activate_test.result_iface != NULL, "Expected to get WASAPI interface, but got NULL\n");
+ IUnknown_Release(async_activate_test.result_iface);
+
+ pWindowsDeleteString(str);
+ }
+
+ /* test default render device creation */
+ hr = IMediaDeviceStatics_GetDefaultAudioRenderId(media_device_statics, AudioDeviceRole_Default, &str);
+ ok(hr == S_OK, "GetDefaultAudioRenderId failed: %08x\n", hr);
+ ok((!!g_default_render_id) == (!!str),
+ "Presence of default render device doesn't match expected state\n");
+
+ if (g_default_render_id)
+ {
+ ok(wcsstr(pWindowsGetStringRawBuffer(str, NULL), g_default_render_id) != NULL,
+ "Expected to find substring of default render id in %s\n",
+ wine_dbgstr_w(pWindowsGetStringRawBuffer(str, NULL)));
+
+ /* returned id does not work in GetDevice... */
+ hr = IMMDeviceEnumerator_GetDevice(g_mmdevenum, pWindowsGetStringRawBuffer(str, NULL), &mmdev);
+ ok(hr == E_INVALIDARG, "GetDevice gave wrong error: %08x\n", hr);
+
+ /* ...but does work in ActivateAudioInterfaceAsync */
+ async_activate_test.ref = 1;
+ async_activate_test.evt = done_evt;
+ async_activate_test.op = NULL;
+ async_activate_test.result_iface = NULL;
+ async_activate_test.result_hr = 0;
+ strcpy(async_activate_test.msg_pfx, "render_activate");
+
+ EnterCriticalSection(&async_activate_test.lock);
+ hr = pActivateAudioInterfaceAsync(pWindowsGetStringRawBuffer(str, NULL),
+ &IID_IAudioClient2, NULL, &async_activate_done, &async_activate_test.op);
+ ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08x\n", hr);
+ LeaveCriticalSection(&async_activate_test.lock);
+
+ IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
+
+ dr = WaitForSingleObject(async_activate_test.evt, 1000); /* wait for all refs other than our own to be released */
+ ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
+ ok(async_activate_test.result_hr == S_OK, "Got unexpected activation result: %08x\n", async_activate_test.result_hr);
+ ok(async_activate_test.result_iface != NULL, "Expected to get WASAPI interface, but got NULL\n");
+ IUnknown_Release(async_activate_test.result_iface);
+
+ pWindowsDeleteString(str);
+ }
+
/* cleanup */
+ CloseHandle(done_evt);
+ DeleteCriticalSection(&async_activate_test.lock);
IMediaDeviceStatics_Release(media_device_statics);
}
START_TEST(devices)
{
- HMODULE combase;
+ HMODULE combase, mmdevapi;
+ IMMDevice *mmdev;
HRESULT hr;
if (!(combase = LoadLibraryW(L"combase.dll")))
@@ -112,12 +286,59 @@ START_TEST(devices)
LOAD_FUNCPTR(RoUninitialize);
LOAD_FUNCPTR(WindowsCreateString);
LOAD_FUNCPTR(WindowsDeleteString);
+ LOAD_FUNCPTR(WindowsGetStringRawBuffer);
+#undef LOAD_FUNCPTR
+
+ if (!(mmdevapi = LoadLibraryW(L"mmdevapi.dll")))
+ {
+ win_skip("Failed to load mmdevapi.dll, skipping tests\n");
+ return;
+ }
+
+#define LOAD_FUNCPTR(x) \
+ if (!(p##x = (void*)GetProcAddress(mmdevapi, #x))) \
+ { \
+ win_skip("Failed to find %s in mmdevapi.dll, skipping tests.\n", #x); \
+ return; \
+ }
+
+ LOAD_FUNCPTR(ActivateAudioInterfaceAsync);
#undef LOAD_FUNCPTR
hr = pRoInitialize(RO_INIT_MULTITHREADED);
ok(hr == S_OK, "RoInitialize failed, hr %#x\n", hr);
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_mmdevenum);
+ ok(hr == S_OK, "Couldn't make MMDeviceEnumerator: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(g_mmdevenum, eCapture, eMultimedia, &mmdev);
+ if (hr == S_OK)
+ {
+ hr = IMMDevice_GetId(mmdev, &g_default_capture_id);
+ ok(hr == S_OK, "IMMDevice::GetId(capture) failed: %08x\n", hr);
+
+ IMMDevice_Release(mmdev);
+ }
+ if (hr != S_OK)
+ g_default_capture_id = NULL;
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(g_mmdevenum, eRender, eMultimedia, &mmdev);
+ if (hr == S_OK)
+ {
+ hr = IMMDevice_GetId(mmdev, &g_default_render_id);
+ ok(hr == S_OK, "IMMDevice::GetId(render) failed: %08x\n", hr);
+
+ IMMDevice_Release(mmdev);
+ }
+ if (hr != S_OK)
+ g_default_render_id = NULL;
+
test_MediaDeviceStatics();
+ CoTaskMemFree(g_default_capture_id);
+ CoTaskMemFree(g_default_render_id);
+ IMMDeviceEnumerator_Release(g_mmdevenum);
+
pRoUninitialize();
}
--
2.31.1
1
0
[PATCH 1/3] mmdevapi: Support device ID paths in ActivateAudioInterfaceAsync
by Andrew Eikum April 13, 2021
by Andrew Eikum April 13, 2021
April 13, 2021
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/mmdevapi/main.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c
index eac1da28f18..e9453da5ad2 100644
--- a/dlls/mmdevapi/main.c
+++ b/dlls/mmdevapi/main.c
@@ -413,6 +413,7 @@ static HRESULT get_mmdevice_by_activatepath(const WCHAR *path, IMMDevice **mmdev
static const WCHAR DEVINTERFACE_AUDIO_RENDER_WSTR[] = L"{E6327CAD-DCEC-4949-AE8A-991E976A79D2}";
static const WCHAR DEVINTERFACE_AUDIO_CAPTURE_WSTR[] = L"{2EEF81BE-33FA-4800-9670-1CD474972C3F}";
+ static const WCHAR MMDEV_PATH_PREFIX[] = L"\\\\?\\SWD#MMDEVAPI#";
hr = MMDevEnum_Create(&IID_IMMDeviceEnumerator, (void**)&devenum);
if (FAILED(hr)) {
@@ -424,8 +425,15 @@ static HRESULT get_mmdevice_by_activatepath(const WCHAR *path, IMMDevice **mmdev
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, eRender, eMultimedia, mmdev);
} else if (!lstrcmpiW(path, DEVINTERFACE_AUDIO_CAPTURE_WSTR)){
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, eCapture, eMultimedia, mmdev);
+ } else if (!memcmp(path, MMDEV_PATH_PREFIX, sizeof(MMDEV_PATH_PREFIX) - sizeof(WCHAR))) {
+ WCHAR device_id[56]; // == strlen("{0.0.1.00000000}.{fd47d9cc-4218-4135-9ce2-0c195c87405b}") + 1
+
+ wcsncpy(device_id, path + (ARRAY_SIZE(MMDEV_PATH_PREFIX) - 1), ARRAY_SIZE(device_id));
+ device_id[ARRAY_SIZE(device_id) - 1] = 0;
+
+ hr = IMMDeviceEnumerator_GetDevice(devenum, device_id, mmdev);
} else {
- FIXME("How to map path to device id? %s\n", debugstr_w(path));
+ FIXME("Unrecognized device id format: %s\n", debugstr_w(path));
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
--
2.31.1
1
0
April 13, 2021
Add references the 'IYUV' mediatype wherever 'I420' is referenced, as
they are identical.
Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com>
---
Somehow this got messed up when I first sent it, I think I may have
accidentally sent this twice.
---
dlls/mfplat/mediatype.c | 3 +++
dlls/mfplat/tests/mfplat.c | 10 ++++++++++
2 files changed, 13 insertions(+)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c
index 85219c74dd5..c8028b2a46f 100644
--- a/dlls/mfplat/mediatype.c
+++ b/dlls/mfplat/mediatype.c
@@ -2634,6 +2634,7 @@ static const struct uncompressed_video_format video_formats[] =
{ &MFVideoFormat_IMC2, 1, 0, 0, 1 },
{ &MFVideoFormat_IMC3, 2, 3, 0, 1 },
{ &MFVideoFormat_IMC4, 1, 0, 0, 1 },
+ { &MFVideoFormat_IYUV, 1, 0, 0, 1 },
{ &MFVideoFormat_NV12, 1, 0, 0, 1 },
{ &MFVideoFormat_D16, 2, 3, 0, 0 },
{ &MFVideoFormat_L16, 2, 3, 0, 0 },
@@ -2716,6 +2717,7 @@ HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height
case MAKEFOURCC('N','V','1','2'):
case MAKEFOURCC('Y','V','1','2'):
case MAKEFOURCC('I','4','2','0'):
+ case MAKEFOURCC('I','Y','U','V'):
/* 2 x 2 block, interleaving UV for half the height */
*size = ((width + 1) & ~1) * height * 3 / 2;
break;
@@ -2758,6 +2760,7 @@ HRESULT WINAPI MFGetPlaneSize(DWORD fourcc, DWORD width, DWORD height, DWORD *si
case MAKEFOURCC('N','V','1','2'):
case MAKEFOURCC('Y','V','1','2'):
case MAKEFOURCC('I','4','2','0'):
+ case MAKEFOURCC('I','Y','U','V'):
*size = stride * height * 3 / 2;
break;
default:
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index c21a57be27f..45781d3725a 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -3965,6 +3965,12 @@ static void test_MFCalculateImageSize(void)
{ &MFVideoFormat_I420, 4, 3, 18 },
{ &MFVideoFormat_I420, 320, 240, 115200 },
+ { &MFVideoFormat_IYUV, 1, 1, 3, 1 },
+ { &MFVideoFormat_IYUV, 2, 1, 3 },
+ { &MFVideoFormat_IYUV, 1, 2, 6, 3 },
+ { &MFVideoFormat_IYUV, 4, 3, 18 },
+ { &MFVideoFormat_IYUV, 320, 240, 115200 },
+
{ &MFVideoFormat_YUY2, 2, 1, 4 },
{ &MFVideoFormat_YUY2, 4, 3, 24 },
{ &MFVideoFormat_YUY2, 128, 128, 32768 },
@@ -5293,6 +5299,10 @@ static void test_MFGetStrideForBitmapInfoHeader(void)
{ &MFVideoFormat_I420, 2, 2 },
{ &MFVideoFormat_I420, 3, 3 },
{ &MFVideoFormat_I420, 320, 320 },
+ { &MFVideoFormat_IYUV, 1, 1 },
+ { &MFVideoFormat_IYUV, 2, 2 },
+ { &MFVideoFormat_IYUV, 3, 3 },
+ { &MFVideoFormat_IYUV, 320, 320 },
};
unsigned int i;
LONG stride;
--
2.25.1
3
2
[PATCH 2/2] windows.media.devices: Stub implement IMediaDeviceStatics
by Andrew Eikum April 13, 2021
by Andrew Eikum April 13, 2021
April 13, 2021
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
configure.ac | 1 +
dlls/windows.media.devices/Makefile.in | 2 +
dlls/windows.media.devices/classes.idl | 24 +++
dlls/windows.media.devices/main.c | 149 ++++++++++++++++++-
dlls/windows.media.devices/tests/Makefile.in | 5 +
dlls/windows.media.devices/tests/devices.c | 123 +++++++++++++++
include/Makefile.in | 1 +
include/windows.media.devices.idl | 126 ++++++++++++++++
8 files changed, 430 insertions(+), 1 deletion(-)
create mode 100644 dlls/windows.media.devices/classes.idl
create mode 100644 dlls/windows.media.devices/tests/Makefile.in
create mode 100644 dlls/windows.media.devices/tests/devices.c
create mode 100644 include/windows.media.devices.idl
diff --git a/configure.ac b/configure.ac
index 408612324b8..6c0c1a33c66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3802,6 +3802,7 @@ WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input/tests)
WINE_CONFIG_MAKEFILE(dlls/windows.globalization)
WINE_CONFIG_MAKEFILE(dlls/windows.globalization/tests)
WINE_CONFIG_MAKEFILE(dlls/windows.media.devices)
+WINE_CONFIG_MAKEFILE(dlls/windows.media.devices/tests)
WINE_CONFIG_MAKEFILE(dlls/windows.media.speech)
WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests)
WINE_CONFIG_MAKEFILE(dlls/windowscodecs)
diff --git a/dlls/windows.media.devices/Makefile.in b/dlls/windows.media.devices/Makefile.in
index b5a3482277c..c0a8649eeb6 100644
--- a/dlls/windows.media.devices/Makefile.in
+++ b/dlls/windows.media.devices/Makefile.in
@@ -5,3 +5,5 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
main.c
+
+IDL_SRCS = classes.idl
diff --git a/dlls/windows.media.devices/classes.idl b/dlls/windows.media.devices/classes.idl
new file mode 100644
index 00000000000..9d6f482d395
--- /dev/null
+++ b/dlls/windows.media.devices/classes.idl
@@ -0,0 +1,24 @@
+/*
+ * Runtime Classes for windows.media.devices.dll
+ *
+ * Copyright 2021 Andrew Eikum for CodeWeavers
+ * Copyright 2021 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma makedep register
+
+#include "windows.media.devices.idl"
diff --git a/dlls/windows.media.devices/main.c b/dlls/windows.media.devices/main.c
index 8e83c4e4061..9797644d71a 100644
--- a/dlls/windows.media.devices/main.c
+++ b/dlls/windows.media.devices/main.c
@@ -29,7 +29,11 @@
#include "activation.h"
+#define WIDL_using_Windows_Foundation
+#define WIDL_using_Windows_Foundation_Collections
#include "windows.foundation.h"
+#define WIDL_using_Windows_Media_Devices
+#include "windows.media.devices.h"
WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
@@ -45,6 +49,7 @@ static const char *debugstr_hstring(HSTRING hstr)
struct windows_media_devices
{
IActivationFactory IActivationFactory_iface;
+ IMediaDeviceStatics IMediaDeviceStatics_iface;
LONG ref;
};
@@ -53,10 +58,17 @@ static inline struct windows_media_devices *impl_from_IActivationFactory(IActiva
return CONTAINING_RECORD(iface, struct windows_media_devices, IActivationFactory_iface);
}
+static inline struct windows_media_devices *impl_from_IMediaDeviceStatics(IMediaDeviceStatics *iface)
+{
+ return CONTAINING_RECORD(iface, struct windows_media_devices, IMediaDeviceStatics_iface);
+}
+
static HRESULT STDMETHODCALLTYPE windows_media_devices_QueryInterface(
IActivationFactory *iface, REFIID iid, void **out)
{
- TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out);
+ struct windows_media_devices *impl = impl_from_IActivationFactory(iface);
+
+ TRACE("iface %p, iid %s, out %p\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_IUnknown) ||
IsEqualGUID(iid, &IID_IInspectable) ||
@@ -68,6 +80,13 @@ static HRESULT STDMETHODCALLTYPE windows_media_devices_QueryInterface(
return S_OK;
}
+ if (IsEqualGUID(iid, &IID_IMediaDeviceStatics))
+ {
+ IUnknown_AddRef(iface);
+ *out = &impl->IMediaDeviceStatics_iface;
+ return S_OK;
+ }
+
FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
*out = NULL;
return E_NOINTERFACE;
@@ -132,9 +151,137 @@ static const struct IActivationFactoryVtbl activation_factory_vtbl =
windows_media_devices_ActivateInstance,
};
+static HRESULT WINAPI media_device_statics_QueryInterface(IMediaDeviceStatics *iface,
+ REFIID riid, void **ppvObject)
+{
+ struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
+ return windows_media_devices_QueryInterface(&This->IActivationFactory_iface, riid, ppvObject);
+}
+
+static ULONG WINAPI media_device_statics_AddRef(IMediaDeviceStatics *iface)
+{
+ struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
+ return windows_media_devices_AddRef(&This->IActivationFactory_iface);
+}
+
+static ULONG WINAPI media_device_statics_Release(IMediaDeviceStatics *iface)
+{
+ struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
+ return windows_media_devices_Release(&This->IActivationFactory_iface);
+}
+
+static HRESULT WINAPI media_device_statics_GetIids(IMediaDeviceStatics *iface,
+ ULONG *iidCount, IID **iids)
+{
+ struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
+ return windows_media_devices_GetIids(&This->IActivationFactory_iface, iidCount, iids);
+}
+
+static HRESULT WINAPI media_device_statics_GetRuntimeClassName(IMediaDeviceStatics *iface,
+ HSTRING *className)
+{
+ struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
+ return windows_media_devices_GetRuntimeClassName(&This->IActivationFactory_iface, className);
+}
+
+static HRESULT WINAPI media_device_statics_GetTrustLevel(IMediaDeviceStatics *iface,
+ TrustLevel *trustLevel)
+{
+ struct windows_media_devices *This = impl_from_IMediaDeviceStatics(iface);
+ return windows_media_devices_GetTrustLevel(&This->IActivationFactory_iface, trustLevel);
+}
+
+static HRESULT WINAPI media_device_statics_GetAudioCaptureSelector(IMediaDeviceStatics *iface,
+ HSTRING *value)
+{
+ FIXME("iface %p, value %p stub!\n", iface, value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_GetAudioRenderSelector(IMediaDeviceStatics *iface,
+ HSTRING *value)
+{
+ FIXME("iface %p, value %p stub!\n", iface, value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_GetVideoCaptureSelector(IMediaDeviceStatics *iface,
+ HSTRING *value)
+{
+ FIXME("iface %p, value %p stub!\n", iface, value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_GetDefaultAudioCaptureId(IMediaDeviceStatics *iface,
+ AudioDeviceRole role, HSTRING *value)
+{
+ FIXME("iface %p, role 0x%x, value %p stub!\n", iface, role, value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_GetDefaultAudioRenderId(IMediaDeviceStatics *iface,
+ AudioDeviceRole role, HSTRING *value)
+{
+ FIXME("iface %p, role 0x%x, value %p stub!\n", iface, role, value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_add_DefaultAudioCaptureDeviceChanged(
+ IMediaDeviceStatics *iface,
+ ITypedEventHandler_IInspectable_DefaultAudioCaptureDeviceChangedEventArgs *handler,
+ EventRegistrationToken *token)
+{
+ FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_remove_DefaultAudioCaptureDeviceChanged(
+ IMediaDeviceStatics *iface,
+ EventRegistrationToken token)
+{
+ FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_add_DefaultAudioRenderDeviceChanged(
+ IMediaDeviceStatics *iface,
+ ITypedEventHandler_IInspectable_DefaultAudioRenderDeviceChangedEventArgs *handler,
+ EventRegistrationToken *token)
+{
+ FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI media_device_statics_remove_DefaultAudioRenderDeviceChanged(
+ IMediaDeviceStatics *iface,
+ EventRegistrationToken token)
+{
+ FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
+ return E_NOTIMPL;
+}
+
+static IMediaDeviceStaticsVtbl media_device_statics_vtbl = {
+ media_device_statics_QueryInterface,
+ media_device_statics_AddRef,
+ media_device_statics_Release,
+ media_device_statics_GetIids,
+ media_device_statics_GetRuntimeClassName,
+ media_device_statics_GetTrustLevel,
+ media_device_statics_GetAudioCaptureSelector,
+ media_device_statics_GetAudioRenderSelector,
+ media_device_statics_GetVideoCaptureSelector,
+ media_device_statics_GetDefaultAudioCaptureId,
+ media_device_statics_GetDefaultAudioRenderId,
+ media_device_statics_add_DefaultAudioCaptureDeviceChanged,
+ media_device_statics_remove_DefaultAudioCaptureDeviceChanged,
+ media_device_statics_add_DefaultAudioRenderDeviceChanged,
+ media_device_statics_remove_DefaultAudioRenderDeviceChanged,
+};
+
static struct windows_media_devices windows_media_devices =
{
{&activation_factory_vtbl},
+ {&media_device_statics_vtbl},
1
};
diff --git a/dlls/windows.media.devices/tests/Makefile.in b/dlls/windows.media.devices/tests/Makefile.in
new file mode 100644
index 00000000000..42aa4ac9b10
--- /dev/null
+++ b/dlls/windows.media.devices/tests/Makefile.in
@@ -0,0 +1,5 @@
+TESTDLL = windows.media.devices.dll
+IMPORTS = ole32
+
+C_SRCS = \
+ devices.c
diff --git a/dlls/windows.media.devices/tests/devices.c b/dlls/windows.media.devices/tests/devices.c
new file mode 100644
index 00000000000..9c3019de773
--- /dev/null
+++ b/dlls/windows.media.devices/tests/devices.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2021 Andrew Eikum for CodeWeavers
+ * Copyright 2021 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#define COBJMACROS
+#include "initguid.h"
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winstring.h"
+
+#include "mmdeviceapi.h"
+#include "audioclient.h"
+#include "roapi.h"
+
+#define WIDL_using_Windows_Foundation
+#define WIDL_using_Windows_Foundation_Collections
+#include "windows.foundation.h"
+#define WIDL_using_Windows_Media_Devices
+#include "windows.media.devices.h"
+
+#include "wine/test.h"
+
+static HRESULT (WINAPI *pRoGetActivationFactory)(HSTRING, REFIID, void **);
+static HRESULT (WINAPI *pRoInitialize)(RO_INIT_TYPE);
+static void (WINAPI *pRoUninitialize)(void);
+static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *);
+static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING);
+
+static void test_MediaDeviceStatics(void)
+{
+ static const WCHAR *media_device_statics_name = L"Windows.Media.Devices.MediaDevice";
+
+ IMediaDeviceStatics *media_device_statics = NULL;
+ IActivationFactory *factory = NULL;
+ IInspectable *inspectable = NULL, *tmp_inspectable = NULL;
+ IAgileObject *agile_object = NULL, *tmp_agile_object = NULL;
+ HSTRING str;
+ HRESULT hr;
+
+ hr = pWindowsCreateString(media_device_statics_name, wcslen(media_device_statics_name), &str);
+ ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr);
+
+ hr = pRoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
+ ok(hr == S_OK, "RoGetActivationFactory failed, hr %#x\n", hr);
+ pWindowsDeleteString(str);
+
+ /* interface tests */
+ hr = IActivationFactory_QueryInterface(factory, &IID_IInspectable, (void **)&inspectable);
+ ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IInspectable failed, hr %#x\n", hr);
+
+ hr = IActivationFactory_QueryInterface(factory, &IID_IAgileObject, (void **)&agile_object);
+ ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IAgileObject failed, hr %#x\n", hr);
+
+ hr = IActivationFactory_QueryInterface(factory, &IID_IMediaDeviceStatics, (void **)&media_device_statics);
+ ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IMediaDeviceStatics failed, hr %#x\n", hr);
+
+ hr = IMediaDeviceStatics_QueryInterface(media_device_statics, &IID_IInspectable, (void **)&tmp_inspectable);
+ ok(hr == S_OK, "IMediaDeviceStatics_QueryInterface IID_IInspectable failed, hr %#x\n", hr);
+ ok(tmp_inspectable == inspectable, "IMediaDeviceStatics_QueryInterface IID_IInspectable returned %p, expected %p\n", tmp_inspectable, inspectable);
+ IInspectable_Release(tmp_inspectable);
+
+ hr = IMediaDeviceStatics_QueryInterface(media_device_statics, &IID_IAgileObject, (void **)&tmp_agile_object);
+ ok(hr == S_OK, "IMediaDeviceStatics_QueryInterface IID_IAgileObject failed, hr %#x\n", hr);
+ ok(tmp_agile_object == agile_object, "IMediaDeviceStatics_QueryInterface IID_IAgileObject returned %p, expected %p\n", tmp_agile_object, agile_object);
+ IAgileObject_Release(tmp_agile_object);
+
+ IAgileObject_Release(agile_object);
+ IInspectable_Release(inspectable);
+ IActivationFactory_Release(factory);
+
+ /* cleanup */
+ IMediaDeviceStatics_Release(media_device_statics);
+}
+
+START_TEST(devices)
+{
+ HMODULE combase;
+ HRESULT hr;
+
+ if (!(combase = LoadLibraryW(L"combase.dll")))
+ {
+ win_skip("Failed to load combase.dll, skipping tests\n");
+ return;
+ }
+
+#define LOAD_FUNCPTR(x) \
+ if (!(p##x = (void*)GetProcAddress(combase, #x))) \
+ { \
+ win_skip("Failed to find %s in combase.dll, skipping tests.\n", #x); \
+ return; \
+ }
+
+ LOAD_FUNCPTR(RoGetActivationFactory);
+ LOAD_FUNCPTR(RoInitialize);
+ LOAD_FUNCPTR(RoUninitialize);
+ LOAD_FUNCPTR(WindowsCreateString);
+ LOAD_FUNCPTR(WindowsDeleteString);
+#undef LOAD_FUNCPTR
+
+ hr = pRoInitialize(RO_INIT_MULTITHREADED);
+ ok(hr == S_OK, "RoInitialize failed, hr %#x\n", hr);
+
+ test_MediaDeviceStatics();
+
+ pRoUninitialize();
+}
diff --git a/include/Makefile.in b/include/Makefile.in
index 3b60e1be303..78297a63524 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -756,6 +756,7 @@ SOURCES = \
windows.gaming.input.idl \
windows.globalization.idl \
windows.h \
+ windows.media.devices.idl \
windows.media.speechsynthesis.idl \
windows.system.idl \
windows.system.userprofile.idl \
diff --git a/include/windows.media.devices.idl b/include/windows.media.devices.idl
new file mode 100644
index 00000000000..d0b3fcef873
--- /dev/null
+++ b/include/windows.media.devices.idl
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2021 Andrew Eikum for CodeWeavers
+ * Copyright 2020 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef __WIDL__
+#pragma winrt ns_prefix
+#endif
+
+import "inspectable.idl";
+import "eventtoken.idl";
+import "windows.foundation.idl";
+
+namespace Windows {
+ namespace Media {
+ namespace Devices {
+ typedef enum AudioDeviceRole AudioDeviceRole;
+ interface IDefaultAudioDeviceChangedEventArgs;
+ interface IMediaDeviceStatics;
+ runtimeclass DefaultAudioCaptureDeviceChangedEventArgs;
+ runtimeclass DefaultAudioRenderDeviceChangedEventArgs;
+ runtimeclass MediaDevice;
+ }
+ }
+}
+
+namespace Windows {
+ namespace Media {
+ namespace Devices {
+ declare {
+ interface Windows.Foundation.TypedEventHandler<IInspectable *, Windows.Media.Devices.DefaultAudioCaptureDeviceChangedEventArgs *>;
+ interface Windows.Foundation.TypedEventHandler<IInspectable *, Windows.Media.Devices.DefaultAudioRenderDeviceChangedEventArgs *>;
+ }
+ }
+ }
+}
+
+namespace Windows {
+ namespace Media {
+ namespace Devices {
+ enum AudioDeviceRole {
+ Default = 0,
+ Communications = 1,
+ };
+ }
+ }
+}
+
+namespace Windows {
+ namespace Media {
+ namespace Devices {
+ [
+ uuid(110f882f-1c05-4657-a18e-47c9b69f07ab)
+ ]
+ interface IDefaultAudioDeviceChangedEventArgs : IInspectable
+ {
+ [propget] HRESULT Id([out] [retval] HSTRING *value);
+ [propget] HRESULT Role([out] [retval] Windows.Media.Devices.AudioDeviceRole *value);
+ }
+
+ [
+ exclusiveto(Windows.Media.Devices.MediaDevice),
+ uuid(aa2d9a40-909f-4bba-bf8b-0c0d296f14f0)
+ ]
+ interface IMediaDeviceStatics : IInspectable
+ {
+ HRESULT GetAudioCaptureSelector([out] [retval] HSTRING *value);
+ HRESULT GetAudioRenderSelector([out] [retval] HSTRING *value);
+ HRESULT GetVideoCaptureSelector([out] [retval] HSTRING *value);
+ HRESULT GetDefaultAudioCaptureId([in] Windows.Media.Devices.AudioDeviceRole role, [out] [retval] HSTRING *value);
+ HRESULT GetDefaultAudioRenderId([in] Windows.Media.Devices.AudioDeviceRole role, [out] [retval] HSTRING *value);
+
+ [eventadd] HRESULT DefaultAudioCaptureDeviceChanged(
+ [in] Windows.Foundation.TypedEventHandler<IInspectable *, Windows.Media.Devices.DefaultAudioCaptureDeviceChangedEventArgs *> *handler,
+ [out, retval] EventRegistrationToken* token);
+ [eventremove] HRESULT DefaultAudioCaptureDeviceChanged(
+ [in] EventRegistrationToken token);
+
+ [eventadd] HRESULT DefaultAudioRenderDeviceChanged(
+ [in] Windows.Foundation.TypedEventHandler<IInspectable *, Windows.Media.Devices.DefaultAudioRenderDeviceChangedEventArgs *> *handler,
+ [out, retval] EventRegistrationToken* token);
+ [eventremove] HRESULT DefaultAudioRenderDeviceChanged(
+ [in] EventRegistrationToken token);
+ }
+
+ [
+ activatable(Windows.Foundation.UniversalApiContract, 1.0),
+ marshaling_behavior(agile),
+ static(Windows.Media.Devices.IMediaDeviceStatics, Windows.Foundation.UniversalApiContract, 1.0),
+ ]
+ runtimeclass MediaDevice
+ {
+ }
+
+ [
+ marshaling_behavior(agile)
+ ]
+ runtimeclass DefaultAudioRenderDeviceChangedEventArgs
+ {
+ [default] interface Windows.Media.Devices.IDefaultAudioDeviceChangedEventArgs;
+ }
+
+ [
+ marshaling_behavior(agile)
+ ]
+ runtimeclass DefaultAudioCaptureDeviceChangedEventArgs
+ {
+ [default] interface Windows.Media.Devices.IDefaultAudioDeviceChangedEventArgs;
+ }
+ }
+ }
+}
--
2.31.1
2
1
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
configure.ac | 1 +
dlls/windows.media.devices/Makefile.in | 7 +
dlls/windows.media.devices/main.c | 158 ++++++++++++++++++
.../windows.media.devices.spec | 3 +
4 files changed, 169 insertions(+)
create mode 100644 dlls/windows.media.devices/Makefile.in
create mode 100644 dlls/windows.media.devices/main.c
create mode 100644 dlls/windows.media.devices/windows.media.devices.spec
diff --git a/configure.ac b/configure.ac
index 5c364bef0d9..408612324b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3801,6 +3801,7 @@ WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input)
WINE_CONFIG_MAKEFILE(dlls/windows.gaming.input/tests)
WINE_CONFIG_MAKEFILE(dlls/windows.globalization)
WINE_CONFIG_MAKEFILE(dlls/windows.globalization/tests)
+WINE_CONFIG_MAKEFILE(dlls/windows.media.devices)
WINE_CONFIG_MAKEFILE(dlls/windows.media.speech)
WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests)
WINE_CONFIG_MAKEFILE(dlls/windowscodecs)
diff --git a/dlls/windows.media.devices/Makefile.in b/dlls/windows.media.devices/Makefile.in
new file mode 100644
index 00000000000..b5a3482277c
--- /dev/null
+++ b/dlls/windows.media.devices/Makefile.in
@@ -0,0 +1,7 @@
+MODULE = windows.media.devices.dll
+IMPORTS = combase
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ main.c
diff --git a/dlls/windows.media.devices/main.c b/dlls/windows.media.devices/main.c
new file mode 100644
index 00000000000..8e83c4e4061
--- /dev/null
+++ b/dlls/windows.media.devices/main.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2021 Andrew Eikum for CodeWeavers
+ * Copyright 2021 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#include "initguid.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winstring.h"
+#include "wine/debug.h"
+#include "objbase.h"
+
+#include "activation.h"
+
+#include "windows.foundation.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
+
+static const char *debugstr_hstring(HSTRING hstr)
+{
+ const WCHAR *str;
+ UINT32 len;
+ if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)";
+ str = WindowsGetStringRawBuffer(hstr, &len);
+ return wine_dbgstr_wn(str, len);
+}
+
+struct windows_media_devices
+{
+ IActivationFactory IActivationFactory_iface;
+ LONG ref;
+};
+
+static inline struct windows_media_devices *impl_from_IActivationFactory(IActivationFactory *iface)
+{
+ return CONTAINING_RECORD(iface, struct windows_media_devices, IActivationFactory_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE windows_media_devices_QueryInterface(
+ IActivationFactory *iface, REFIID iid, void **out)
+{
+ TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) ||
+ IsEqualGUID(iid, &IID_IInspectable) ||
+ IsEqualGUID(iid, &IID_IAgileObject) ||
+ IsEqualGUID(iid, &IID_IActivationFactory))
+ {
+ IUnknown_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE windows_media_devices_AddRef(
+ IActivationFactory *iface)
+{
+ struct windows_media_devices *impl = impl_from_IActivationFactory(iface);
+ ULONG ref = InterlockedIncrement(&impl->ref);
+ TRACE("iface %p, ref %u.\n", iface, ref);
+ return ref;
+}
+
+static ULONG STDMETHODCALLTYPE windows_media_devices_Release(
+ IActivationFactory *iface)
+{
+ struct windows_media_devices *impl = impl_from_IActivationFactory(iface);
+ ULONG ref = InterlockedDecrement(&impl->ref);
+ TRACE("iface %p, ref %u.\n", iface, ref);
+ return ref;
+}
+
+static HRESULT STDMETHODCALLTYPE windows_media_devices_GetIids(
+ IActivationFactory *iface, ULONG *iid_count, IID **iids)
+{
+ FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE windows_media_devices_GetRuntimeClassName(
+ IActivationFactory *iface, HSTRING *class_name)
+{
+ FIXME("iface %p, class_name %p stub!\n", iface, class_name);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE windows_media_devices_GetTrustLevel(
+ IActivationFactory *iface, TrustLevel *trust_level)
+{
+ FIXME("iface %p, trust_level %p stub!\n", iface, trust_level);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE windows_media_devices_ActivateInstance(
+ IActivationFactory *iface, IInspectable **instance)
+{
+ FIXME("iface %p, instance %p stub!\n", iface, instance);
+ return E_NOTIMPL;
+}
+
+static const struct IActivationFactoryVtbl activation_factory_vtbl =
+{
+ windows_media_devices_QueryInterface,
+ windows_media_devices_AddRef,
+ windows_media_devices_Release,
+ /* IInspectable methods */
+ windows_media_devices_GetIids,
+ windows_media_devices_GetRuntimeClassName,
+ windows_media_devices_GetTrustLevel,
+ /* IActivationFactory methods */
+ windows_media_devices_ActivateInstance,
+};
+
+static struct windows_media_devices windows_media_devices =
+{
+ {&activation_factory_vtbl},
+ 1
+};
+
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+ return S_FALSE;
+}
+
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out)
+{
+ FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out);
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory)
+{
+ TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory);
+ *factory = &windows_media_devices.IActivationFactory_iface;
+ IUnknown_AddRef(*factory);
+ return S_OK;
+}
diff --git a/dlls/windows.media.devices/windows.media.devices.spec b/dlls/windows.media.devices/windows.media.devices.spec
new file mode 100644
index 00000000000..721493229c2
--- /dev/null
+++ b/dlls/windows.media.devices/windows.media.devices.spec
@@ -0,0 +1,3 @@
+1 stdcall -private DllCanUnloadNow()
+2 stdcall -private DllGetActivationFactory(ptr ptr)
+3 stdcall -private DllGetClassObject(ptr ptr ptr)
--
2.31.1
1
0
April 13, 2021
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
In preparation for split PE/.so parts.
dlls/winevulkan/make_vulkan | 8 +--
dlls/winevulkan/vulkan.c | 111 ++++++++++++++++++------------------
2 files changed, 60 insertions(+), 59 deletions(-)
4
11