Alexandre Julliard : widl: Fix representation of context handles in the format string.
Alexandre Julliard
julliard at winehq.org
Thu Jun 2 11:22:58 CDT 2011
Module: wine
Branch: master
Commit: 5e67dcd10f2ae33f5ad26aa23aa59a52cb792bf0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5e67dcd10f2ae33f5ad26aa23aa59a52cb792bf0
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jun 1 20:21:37 2011 +0200
widl: Fix representation of context handles in the format string.
---
tools/widl/header.c | 20 +++++++++++++++++++
tools/widl/header.h | 1 +
tools/widl/typegen.c | 52 +++++++++++++++++++++++++++++++++++--------------
3 files changed, 58 insertions(+), 15 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 574f723..1a71cef 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -439,6 +439,26 @@ static int generic_handle_registered(const char *name)
return 0;
}
+unsigned int get_context_handle_offset( const type_t *type )
+{
+ context_handle_t *ch;
+ unsigned int index = 0;
+
+ while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
+ {
+ if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+ else if (is_ptr( type )) type = type_pointer_get_ref( type );
+ else error( "internal error: %s is not a context handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
+ {
+ if (!strcmp( type->name, ch->name )) return index;
+ index++;
+ }
+ error( "internal error: %s is not registered as a context handle\n", type->name );
+ return index;
+}
+
/* check for types which require additional prototypes to be generated in the
* header */
void check_for_additional_prototype_types(const var_list_t *list)
diff --git a/tools/widl/header.h b/tools/widl/header.h
index c844850..ba28229 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -36,6 +36,7 @@ extern void write_type_left(FILE *h, type_t *t, int declonly);
extern void write_type_right(FILE *h, type_t *t, int is_field);
extern void write_type_decl(FILE *f, type_t *t, const char *name);
extern void write_type_decl_left(FILE *f, type_t *t);
+extern unsigned int get_context_handle_offset( const type_t *type );
extern int needs_space_after(type_t *t);
extern int is_object(const type_t *iface);
extern int is_local(const attr_list_t *list);
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 8d93b331a..2e763be 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -370,6 +370,28 @@ static unsigned int get_stack_size( const type_t *type, const attr_list_t *attrs
return ROUND_SIZE( stack_size, pointer_size );
}
+static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs,
+ const type_t *type )
+{
+ unsigned char flags = 0;
+
+ if (is_attr(iface->attrs, ATTR_STRICTCONTEXTHANDLE)) flags |= NDR_STRICT_CONTEXT_HANDLE;
+
+ if (is_ptr(type) &&
+ !is_attr( type->attrs, ATTR_CONTEXTHANDLE ) &&
+ !is_attr( attrs, ATTR_CONTEXTHANDLE ))
+ flags |= 0x80;
+
+ if (is_attr(attrs, ATTR_IN))
+ {
+ flags |= 0x40;
+ if (!is_attr(attrs, ATTR_OUT)) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
+ }
+ if (is_attr(attrs, ATTR_OUT)) flags |= 0x20;
+
+ return flags;
+}
+
unsigned char get_struct_fc(const type_t *type)
{
int has_pointer = 0;
@@ -2939,27 +2961,26 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
static unsigned int write_contexthandle_tfs(FILE *file,
const attr_list_t *attrs,
- const type_t *type,
+ type_t *type,
+ int toplevel_param,
unsigned int *typeformat_offset)
{
unsigned int start_offset = *typeformat_offset;
- unsigned char flags = 0;
+ unsigned char flags = get_contexthandle_flags( current_iface, attrs, type );
- if (is_attr(current_iface->attrs, ATTR_STRICTCONTEXTHANDLE))
- flags |= NDR_STRICT_CONTEXT_HANDLE;
+ print_start_tfs_comment(file, type, start_offset);
- if (is_ptr(type))
- flags |= 0x80;
- if (is_attr(attrs, ATTR_IN))
+ if (flags & 0x80) /* via ptr */
{
- flags |= 0x40;
- if (!is_attr(attrs, ATTR_OUT))
- flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
+ int pointer_type = get_pointer_fc( type, attrs, toplevel_param );
+ if (!pointer_type) pointer_type = RPC_FC_RP;
+ *typeformat_offset += 4;
+ print_file(file, 2,"0x%x, 0x0,\t/* %s */\n", pointer_type, string_of_type(pointer_type) );
+ print_file(file, 2, "NdrFcShort(0x2),\t /* Offset= 2 (%u) */\n", *typeformat_offset);
+ print_file(file, 0, "/* %2u */\n", *typeformat_offset);
}
- if (is_attr(attrs, ATTR_OUT))
- flags |= 0x20;
- WRITE_FCTYPE(file, FC_BIND_CONTEXT, *typeformat_offset);
+ print_file(file, 2, "0x%02x,\t/* FC_BIND_CONTEXT */\n", RPC_FC_BIND_CONTEXT);
print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
/* return and can't be null values overlap */
if (((flags & 0x21) != 0x21) && (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL))
@@ -2979,7 +3000,7 @@ static unsigned int write_contexthandle_tfs(FILE *file,
if (flags & 0x80)
print_file(file, 0, "via ptr, ");
print_file(file, 0, "*/\n");
- print_file(file, 2, "0, /* FIXME: rundown routine index*/\n");
+ print_file(file, 2, "0x%x,\t/* rundown routine */\n", get_context_handle_offset( type ));
print_file(file, 2, "0, /* FIXME: param num */\n");
*typeformat_offset += 4;
@@ -3025,7 +3046,8 @@ static unsigned int write_type_tfs(FILE *file, int indent,
{
case TGT_CTXT_HANDLE:
case TGT_CTXT_HANDLE_POINTER:
- return write_contexthandle_tfs(file, attrs, type, typeformat_offset);
+ return write_contexthandle_tfs(file, attrs, type,
+ context == TYPE_CONTEXT_TOPLEVELPARAM, typeformat_offset);
case TGT_USER_TYPE:
return write_user_tfs(file, type, typeformat_offset);
case TGT_STRING:
More information about the wine-cvs
mailing list