mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
widl: Implement support for pointers to base types.
This commit is contained in:
parent
e97a1afbab
commit
1a5c6ef47d
@ -88,6 +88,29 @@ static void print_message_buffer_size(const func_t *func)
|
||||
}
|
||||
|
||||
|
||||
static int has_out_arg_or_return(const func_t *func)
|
||||
{
|
||||
var_t *var;
|
||||
|
||||
if (!is_void(func->def->type, NULL))
|
||||
return 1;
|
||||
|
||||
if (!func->args)
|
||||
return 0;
|
||||
|
||||
var = func->args;
|
||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||
while (var)
|
||||
{
|
||||
if (is_attr(var->attrs, ATTR_OUT))
|
||||
return 1;
|
||||
|
||||
var = PREV_LINK(var);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void write_function_stubs(type_t *iface)
|
||||
{
|
||||
const func_t *func = iface->funcs;
|
||||
@ -212,13 +235,9 @@ static void write_function_stubs(type_t *iface)
|
||||
indent--;
|
||||
|
||||
print_client("_StubMsg.BufferStart = (unsigned char *)_RpcMessage.Buffer;\n");
|
||||
print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n\n");
|
||||
print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n");
|
||||
|
||||
/* unmarshall arguments */
|
||||
write_remoting_arguments(client, indent, func, &type_offset, PASS_OUT, PHASE_UNMARSHAL);
|
||||
|
||||
/* unmarshal return value */
|
||||
if (!is_void(def->type, NULL))
|
||||
if (has_out_arg_or_return(func))
|
||||
{
|
||||
fprintf(client, "\n");
|
||||
|
||||
@ -229,8 +248,16 @@ static void write_function_stubs(type_t *iface)
|
||||
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
|
||||
print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);
|
||||
indent -= 2;
|
||||
fprintf(client, "\n");
|
||||
}
|
||||
|
||||
/* unmarshall arguments */
|
||||
fprintf(client, "\n");
|
||||
write_remoting_arguments(client, indent, func, &type_offset, PASS_OUT, PHASE_UNMARSHAL);
|
||||
|
||||
/* unmarshal return value */
|
||||
if (!is_void(def->type, NULL))
|
||||
{
|
||||
fprintf(client, "\n");
|
||||
print_client("_RetVal = *(");
|
||||
write_type(client, def->type, def, def->tname);
|
||||
fprintf(client, " *)_StubMsg.Buffer;\n");
|
||||
|
@ -88,6 +88,77 @@ static void write_parameters_init(const func_t *func)
|
||||
}
|
||||
|
||||
|
||||
static void declare_args(const func_t *func)
|
||||
{
|
||||
int in_attr, out_attr;
|
||||
int i = 0;
|
||||
var_t *var;
|
||||
|
||||
if (!func->args)
|
||||
return;
|
||||
|
||||
var = func->args;
|
||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||
while (var)
|
||||
{
|
||||
in_attr = is_attr(var->attrs, ATTR_IN);
|
||||
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||
if (!out_attr && !in_attr)
|
||||
in_attr = 1;
|
||||
|
||||
if (!in_attr)
|
||||
{
|
||||
print_server("");
|
||||
write_type(server, var->type, NULL, var->tname);
|
||||
fprintf(server, " _W%u;\n", i++);
|
||||
}
|
||||
|
||||
print_server("");
|
||||
write_type(server, var->type, var, var->tname);
|
||||
fprintf(server, " ");
|
||||
write_name(server, var);
|
||||
write_array(server, var->array, 0);
|
||||
fprintf(server, ";\n");
|
||||
|
||||
var = PREV_LINK(var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void assign_out_args(const func_t *func)
|
||||
{
|
||||
int in_attr, out_attr;
|
||||
int i = 0, sep = 0;
|
||||
var_t *var;
|
||||
|
||||
if (!func->args)
|
||||
return;
|
||||
|
||||
var = func->args;
|
||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||
while (var)
|
||||
{
|
||||
in_attr = is_attr(var->attrs, ATTR_IN);
|
||||
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||
if (!out_attr && !in_attr)
|
||||
in_attr = 1;
|
||||
|
||||
if (!in_attr)
|
||||
{
|
||||
print_server("");
|
||||
write_name(server, var);
|
||||
fprintf(server, " = &_W%u;\n", i++);
|
||||
sep = 1;
|
||||
}
|
||||
|
||||
var = PREV_LINK(var);
|
||||
}
|
||||
|
||||
if (sep)
|
||||
fprintf(server, "\n");
|
||||
}
|
||||
|
||||
|
||||
static void write_function_stubs(type_t *iface)
|
||||
{
|
||||
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
|
||||
@ -144,23 +215,8 @@ static void write_function_stubs(type_t *iface)
|
||||
fprintf(server, " _RetVal;\n");
|
||||
}
|
||||
|
||||
/* declare arguments */
|
||||
if (func->args)
|
||||
{
|
||||
var = func->args;
|
||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||
while (var)
|
||||
{
|
||||
print_server("");
|
||||
write_type(server, var->type, var, var->tname);
|
||||
fprintf(server, " ");
|
||||
write_name(server, var);
|
||||
write_array(server, var->array, 0);
|
||||
fprintf(server, ";\n");
|
||||
|
||||
var = PREV_LINK(var);
|
||||
}
|
||||
}
|
||||
/* Declare arguments */
|
||||
declare_args(func);
|
||||
|
||||
print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
|
||||
print_server("RPC_STATUS _Status;\n");
|
||||
@ -226,6 +282,8 @@ static void write_function_stubs(type_t *iface)
|
||||
print_server("RpcEndExcept\n");
|
||||
fprintf(server, "\n");
|
||||
|
||||
/* Assign 'out' arguments */
|
||||
assign_out_args(func);
|
||||
|
||||
/* Call the real server function */
|
||||
if (!is_void(def->type, NULL))
|
||||
|
@ -1181,6 +1181,8 @@ static size_t write_typeformatstring_var(FILE *file, int indent,
|
||||
else if (ptr_level == 1 && !type_has_ref(type))
|
||||
{
|
||||
size_t start_offset = *typeformat_offset;
|
||||
int in_attr = is_attr(var->attrs, ATTR_IN);
|
||||
int out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||
int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
|
||||
if (!pointer_type) pointer_type = RPC_FC_RP;
|
||||
|
||||
@ -1189,9 +1191,11 @@ static size_t write_typeformatstring_var(FILE *file, int indent,
|
||||
{
|
||||
#define CASE_BASETYPE(fctype) \
|
||||
case RPC_##fctype: \
|
||||
print_file(file, indent, "0x%x, 0x08, /* %s [simple_pointer] */\n", \
|
||||
print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", \
|
||||
pointer_type, \
|
||||
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP")); \
|
||||
(!in_attr && out_attr) ? 0x0C : 0x08, \
|
||||
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), \
|
||||
(!in_attr && out_attr) ? "[allocated_on_stack] " : ""); \
|
||||
print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
|
||||
print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
|
||||
*typeformat_offset += 4; \
|
||||
@ -1331,6 +1335,8 @@ static unsigned int get_required_buffer_size_type(
|
||||
}
|
||||
if (ptr_level == 0 && type_has_ref(type))
|
||||
return get_required_buffer_size_type(type->ref, 0 /* FIXME */, array, name, alignment);
|
||||
if (ptr_level == 1)
|
||||
return 25; /* FIXME: Only 'in' pointers need this */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1557,9 +1563,91 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
|
||||
}
|
||||
else
|
||||
{
|
||||
int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
|
||||
if (!pointer_type)
|
||||
pointer_type = RPC_FC_RP;
|
||||
|
||||
if (pointer_type == RPC_FC_RP)
|
||||
{
|
||||
unsigned int size;
|
||||
switch (var->type->type)
|
||||
{
|
||||
case RPC_FC_BYTE:
|
||||
case RPC_FC_CHAR:
|
||||
case RPC_FC_SMALL:
|
||||
case RPC_FC_USMALL:
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
case RPC_FC_WCHAR:
|
||||
case RPC_FC_USHORT:
|
||||
case RPC_FC_SHORT:
|
||||
size = 2;
|
||||
break;
|
||||
|
||||
case RPC_FC_ULONG:
|
||||
case RPC_FC_LONG:
|
||||
case RPC_FC_FLOAT:
|
||||
case RPC_FC_ERROR_STATUS_T:
|
||||
size = 4;
|
||||
break;
|
||||
|
||||
case RPC_FC_HYPER:
|
||||
case RPC_FC_DOUBLE:
|
||||
size = 8;
|
||||
break;
|
||||
|
||||
case RPC_FC_IGNORE:
|
||||
case RPC_FC_BIND_PRIMITIVE:
|
||||
/* no marshalling needed */
|
||||
continue;
|
||||
|
||||
default:
|
||||
error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, var->type->type);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
print_file(file, indent,
|
||||
"NdrPointer%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
|
||||
function_from_phase(phase), var->name, *type_offset);
|
||||
"_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n",
|
||||
size - 1, size - 1);
|
||||
|
||||
if (phase == PHASE_MARSHAL)
|
||||
{
|
||||
print_file(file, indent, "*(");
|
||||
write_type(file, var->type, NULL, var->tname);
|
||||
fprintf(file, " *)_StubMsg.Buffer = *");
|
||||
write_name(file, var);
|
||||
fprintf(file, ";\n");
|
||||
}
|
||||
else if (phase == PHASE_UNMARSHAL)
|
||||
{
|
||||
print_file(file, indent, (pass == PASS_IN) ? "" : "*");
|
||||
write_name(file, var);
|
||||
fprintf(file, (pass == PASS_IN) ? " = (" : " = *(");
|
||||
write_type(file, var->type, NULL, var->tname);
|
||||
fprintf(file, " *)_StubMsg.Buffer;\n");
|
||||
}
|
||||
|
||||
print_file(file, indent, "_StubMsg.Buffer += sizeof(");
|
||||
write_type(file, var->type, NULL, var->tname);
|
||||
fprintf(file, ");\n");
|
||||
}
|
||||
else if (pointer_type == RPC_FC_UP)
|
||||
{
|
||||
print_file(file, indent, "NdrPointer%s(\n", function_from_phase(phase));
|
||||
indent++;
|
||||
print_file(file, indent, "(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
|
||||
print_file(file, indent, "(unsigned char *)%s,\n", var->name);
|
||||
print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
|
||||
*type_offset, (phase == PHASE_MARSHAL) ? ");" : ",");
|
||||
if (phase == PHASE_UNMARSHAL)
|
||||
print_file(file, indent, "(unsigned char *)0);\n");
|
||||
indent--;
|
||||
}
|
||||
else if (pointer_type == RPC_FC_FP)
|
||||
{
|
||||
error("write_remoting_arguments: Unimplemented for full pointers to base types\n");
|
||||
}
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user