mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 21:38:43 +00:00
Implement [in], [out] and [in, out] support for pointers to basic types.
svn path=/trunk/; revision=13966
This commit is contained in:
parent
466b206539
commit
8871c0355a
3 changed files with 574 additions and 92 deletions
|
@ -1,5 +1,13 @@
|
||||||
ChangeLog
|
ChangeLog
|
||||||
|
|
||||||
|
2005-03-12 ekohl
|
||||||
|
|
||||||
|
tools/widl/client.c
|
||||||
|
tools/widl/server.c
|
||||||
|
|
||||||
|
Implement [in], [out] and [in, out] support for pointers to basic types.
|
||||||
|
|
||||||
|
|
||||||
2005-03-10 ekohl
|
2005-03-10 ekohl
|
||||||
|
|
||||||
tools/widl/client.c
|
tools/widl/client.c
|
||||||
|
|
|
@ -61,6 +61,7 @@ static void write_procformatstring(type_t *iface)
|
||||||
func_t *func = iface->funcs;
|
func_t *func = iface->funcs;
|
||||||
var_t *var;
|
var_t *var;
|
||||||
unsigned int type_offset = 2;
|
unsigned int type_offset = 2;
|
||||||
|
int in_attr, out_attr;
|
||||||
|
|
||||||
print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
|
print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
|
||||||
print_client("{\n");
|
print_client("{\n");
|
||||||
|
@ -79,6 +80,13 @@ static void write_procformatstring(type_t *iface)
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
while (var)
|
while (var)
|
||||||
{
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
in_attr = is_attr(var->attrs, ATTR_IN);
|
||||||
|
|
||||||
|
/* set 'in' attribute if neither 'in' nor 'out' is set */
|
||||||
|
if (!out_attr && !in_attr)
|
||||||
|
in_attr = 1;
|
||||||
|
|
||||||
if (var->ptr_level == 0)
|
if (var->ptr_level == 0)
|
||||||
{
|
{
|
||||||
if (is_base_type(var->type))
|
if (is_base_type(var->type))
|
||||||
|
@ -96,7 +104,12 @@ static void write_procformatstring(type_t *iface)
|
||||||
{
|
{
|
||||||
if (is_base_type(var->type))
|
if (is_base_type(var->type))
|
||||||
{
|
{
|
||||||
|
if (in_attr & !out_attr)
|
||||||
print_client("0x4d, /* FC_IN_PARAM */\n");
|
print_client("0x4d, /* FC_IN_PARAM */\n");
|
||||||
|
else if (!in_attr & out_attr)
|
||||||
|
print_client("0x51, /* FC_OUT_PARAM */\n");
|
||||||
|
else if (in_attr & out_attr)
|
||||||
|
print_client("0x50, /* FC_IN_OUT_PARAM */\n");
|
||||||
fprintf(client, "#ifndef _ALPHA_\n");
|
fprintf(client, "#ifndef _ALPHA_\n");
|
||||||
print_client("0x01,\n");
|
print_client("0x01,\n");
|
||||||
fprintf(client, "#else\n");
|
fprintf(client, "#else\n");
|
||||||
|
@ -150,6 +163,7 @@ static void write_typeformatstring(type_t *iface)
|
||||||
{
|
{
|
||||||
func_t *func = iface->funcs;
|
func_t *func = iface->funcs;
|
||||||
var_t *var;
|
var_t *var;
|
||||||
|
int out_attr;
|
||||||
|
|
||||||
print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
|
print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
|
||||||
print_client("{\n");
|
print_client("{\n");
|
||||||
|
@ -168,6 +182,8 @@ static void write_typeformatstring(type_t *iface)
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
while (var)
|
while (var)
|
||||||
{
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
|
||||||
if (var->ptr_level > 1)
|
if (var->ptr_level > 1)
|
||||||
{
|
{
|
||||||
error("Function '%s' argument '%s': Pointer level %d not supported!\n",
|
error("Function '%s' argument '%s': Pointer level %d not supported!\n",
|
||||||
|
@ -179,6 +195,9 @@ static void write_typeformatstring(type_t *iface)
|
||||||
{
|
{
|
||||||
if (is_base_type(var->type))
|
if (is_base_type(var->type))
|
||||||
{
|
{
|
||||||
|
if (out_attr)
|
||||||
|
print_client("0x11, 0x0c, /* FC_RP [allocated_on_stack] [simple_pointer] */\n");
|
||||||
|
else
|
||||||
print_client("0x11, 0x08, /* FC_RP [simple_pointer] */\n");
|
print_client("0x11, 0x08, /* FC_RP [simple_pointer] */\n");
|
||||||
print_client("0x%02x, /* FC_<type> */\n", var->type->type);
|
print_client("0x%02x, /* FC_<type> */\n", var->type->type);
|
||||||
print_client("0x5c, /* FC_PAD */\n");
|
print_client("0x5c, /* FC_PAD */\n");
|
||||||
|
@ -210,14 +229,11 @@ static void print_message_buffer_size(func_t *func)
|
||||||
int last_size = -1;
|
int last_size = -1;
|
||||||
int in_attr;
|
int in_attr;
|
||||||
int out_attr;
|
int out_attr;
|
||||||
|
int nothing_printed = 1;
|
||||||
var_t *var;
|
var_t *var;
|
||||||
|
|
||||||
if (!func->args)
|
if (func->args)
|
||||||
{
|
{
|
||||||
fprintf(client, " 0U");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var = func->args;
|
var = func->args;
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
for (; var; var = PREV_LINK(var))
|
for (; var; var = PREV_LINK(var))
|
||||||
|
@ -271,16 +287,24 @@ static void print_message_buffer_size(func_t *func)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error("Unknown/unsupported type!");
|
error("Unknown/unsupported type!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_size != -1)
|
if (last_size != -1)
|
||||||
fprintf(client, " +");
|
fprintf(client, " +");
|
||||||
fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
|
fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
|
||||||
|
nothing_printed = 0;
|
||||||
|
|
||||||
last_size = size;
|
last_size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nothing_printed)
|
||||||
|
{
|
||||||
|
fprintf(client, " 0U");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void marshall_in_arguments(func_t *func)
|
static void marshall_in_arguments(func_t *func)
|
||||||
{
|
{
|
||||||
|
@ -376,6 +400,137 @@ static void marshall_in_arguments(func_t *func)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void unmarshall_out_arguments(func_t *func)
|
||||||
|
{
|
||||||
|
unsigned int alignment;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int last_size = 0;
|
||||||
|
int out_attr;
|
||||||
|
var_t *var;
|
||||||
|
var_t *def;
|
||||||
|
|
||||||
|
def = func->def;
|
||||||
|
|
||||||
|
/* unmarshall the out arguments */
|
||||||
|
if (func->args)
|
||||||
|
{
|
||||||
|
var = func->args;
|
||||||
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
|
for (; var; var = PREV_LINK(var))
|
||||||
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
if (!out_attr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (var->ptr_level > 1)
|
||||||
|
{
|
||||||
|
error("Function '%s' argument '%s': Pointer level %d not supported!\n",
|
||||||
|
func->def->name, var->name, var->ptr_level);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alignment = 0;
|
||||||
|
switch (var->type->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_BYTE:
|
||||||
|
case RPC_FC_CHAR:
|
||||||
|
case RPC_FC_SMALL:
|
||||||
|
size = 1;
|
||||||
|
alignment = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_WCHAR:
|
||||||
|
case RPC_FC_USHORT:
|
||||||
|
case RPC_FC_SHORT:
|
||||||
|
size = 2;
|
||||||
|
if (last_size > 0 && last_size < 2)
|
||||||
|
alignment = (2 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_ULONG:
|
||||||
|
case RPC_FC_LONG:
|
||||||
|
case RPC_FC_FLOAT:
|
||||||
|
size = 4;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_HYPER:
|
||||||
|
case RPC_FC_DOUBLE:
|
||||||
|
size = 8;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_IGNORE:
|
||||||
|
size = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("Unknown/unsupported type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != 0)
|
||||||
|
{
|
||||||
|
if (var->ptr_level == 1)
|
||||||
|
{
|
||||||
|
fprintf(client, "\n");
|
||||||
|
if (alignment != 0)
|
||||||
|
print_client("_StubMsg.Buffer += %u;\n", alignment);
|
||||||
|
|
||||||
|
print_client("*");
|
||||||
|
write_name(client, var);
|
||||||
|
fprintf(client, " = *((");
|
||||||
|
write_type(client, var->type, NULL, var->tname);
|
||||||
|
fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
last_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unmarshall return value */
|
||||||
|
if (!is_void(def->type, NULL))
|
||||||
|
{
|
||||||
|
alignment = 0;
|
||||||
|
switch (def->type->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_BYTE:
|
||||||
|
case RPC_FC_CHAR:
|
||||||
|
case RPC_FC_SMALL:
|
||||||
|
case RPC_FC_WCHAR:
|
||||||
|
case RPC_FC_USHORT:
|
||||||
|
case RPC_FC_SHORT:
|
||||||
|
case RPC_FC_ULONG:
|
||||||
|
case RPC_FC_LONG:
|
||||||
|
case RPC_FC_FLOAT:
|
||||||
|
size = 4;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_HYPER:
|
||||||
|
case RPC_FC_DOUBLE:
|
||||||
|
size = 8;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("Unknown/unsupported type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(client, "\n");
|
||||||
|
if (alignment != 0)
|
||||||
|
print_client("_StubMsg.Buffer += %u;\n", alignment);
|
||||||
|
print_client("_RetVal = *((");
|
||||||
|
write_type(client, def->type, def, def->tname);
|
||||||
|
fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void check_pointers(func_t *func)
|
static void check_pointers(func_t *func)
|
||||||
{
|
{
|
||||||
var_t *var;
|
var_t *var;
|
||||||
|
@ -408,6 +563,30 @@ static void check_pointers(func_t *func)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int use_return_buffer(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)
|
static void write_function_stubs(type_t *iface)
|
||||||
{
|
{
|
||||||
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
|
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
|
||||||
|
@ -523,11 +702,10 @@ static void write_function_stubs(type_t *iface)
|
||||||
print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");
|
print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");
|
||||||
indent--;
|
indent--;
|
||||||
|
|
||||||
/* convert data representation */
|
if (use_return_buffer(func))
|
||||||
if (!is_void(def->type, NULL))
|
|
||||||
{
|
{
|
||||||
|
/* convert data representation */
|
||||||
fprintf(client, "\n");
|
fprintf(client, "\n");
|
||||||
|
|
||||||
print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
|
print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
|
||||||
indent++;
|
indent++;
|
||||||
print_client("NdrConvert(\n");
|
print_client("NdrConvert(\n");
|
||||||
|
@ -535,11 +713,9 @@ static void write_function_stubs(type_t *iface)
|
||||||
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
|
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
|
||||||
print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);
|
print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);
|
||||||
indent -= 2;
|
indent -= 2;
|
||||||
fprintf(client, "\n");
|
|
||||||
|
|
||||||
print_client("_RetVal = *((");
|
/* unmarshal out arguments */
|
||||||
write_type(client, def->type, def, def->tname);
|
unmarshall_out_arguments(func);
|
||||||
fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update proc_offset */
|
/* update proc_offset */
|
||||||
|
|
|
@ -66,6 +66,7 @@ static void write_procformatstring(type_t *iface)
|
||||||
func_t *func = iface->funcs;
|
func_t *func = iface->funcs;
|
||||||
var_t *var;
|
var_t *var;
|
||||||
unsigned int type_offset = 2;
|
unsigned int type_offset = 2;
|
||||||
|
int in_attr, out_attr;
|
||||||
|
|
||||||
print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
|
print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
|
||||||
print_server("{\n");
|
print_server("{\n");
|
||||||
|
@ -84,6 +85,13 @@ static void write_procformatstring(type_t *iface)
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
while (var)
|
while (var)
|
||||||
{
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
in_attr = is_attr(var->attrs, ATTR_IN);
|
||||||
|
|
||||||
|
/* set 'in' attribute if neither 'in' nor 'out' is set */
|
||||||
|
if (!out_attr && !in_attr)
|
||||||
|
in_attr = 1;
|
||||||
|
|
||||||
if (var->ptr_level == 0)
|
if (var->ptr_level == 0)
|
||||||
{
|
{
|
||||||
if (is_base_type(var->type))
|
if (is_base_type(var->type))
|
||||||
|
@ -101,7 +109,12 @@ static void write_procformatstring(type_t *iface)
|
||||||
{
|
{
|
||||||
if (is_base_type(var->type))
|
if (is_base_type(var->type))
|
||||||
{
|
{
|
||||||
|
if (in_attr & !out_attr)
|
||||||
print_server("0x4d, /* FC_IN_PARAM */\n");
|
print_server("0x4d, /* FC_IN_PARAM */\n");
|
||||||
|
else if (!in_attr & out_attr)
|
||||||
|
print_server("0x51, /* FC_OUT_PARAM */\n");
|
||||||
|
else if (in_attr & out_attr)
|
||||||
|
print_server("0x50, /* FC_IN_OUT_PARAM */\n");
|
||||||
fprintf(server, "#ifndef _ALPHA_\n");
|
fprintf(server, "#ifndef _ALPHA_\n");
|
||||||
print_server("0x01,\n");
|
print_server("0x01,\n");
|
||||||
fprintf(server, "#else\n");
|
fprintf(server, "#else\n");
|
||||||
|
@ -155,6 +168,7 @@ static void write_typeformatstring(type_t *iface)
|
||||||
{
|
{
|
||||||
func_t *func = iface->funcs;
|
func_t *func = iface->funcs;
|
||||||
var_t *var;
|
var_t *var;
|
||||||
|
int out_attr;
|
||||||
|
|
||||||
print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
|
print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
|
||||||
print_server("{\n");
|
print_server("{\n");
|
||||||
|
@ -173,6 +187,8 @@ static void write_typeformatstring(type_t *iface)
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
while (var)
|
while (var)
|
||||||
{
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
|
||||||
if (var->ptr_level > 1)
|
if (var->ptr_level > 1)
|
||||||
{
|
{
|
||||||
error("Function '%s' argument '%s': Pointer level %d not supported!\n",
|
error("Function '%s' argument '%s': Pointer level %d not supported!\n",
|
||||||
|
@ -184,6 +200,9 @@ static void write_typeformatstring(type_t *iface)
|
||||||
{
|
{
|
||||||
if (is_base_type(var->type))
|
if (is_base_type(var->type))
|
||||||
{
|
{
|
||||||
|
if (out_attr)
|
||||||
|
print_server("0x11, 0x0c, /* FC_RP [allocated_on_stack] [simple_pointer] */\n");
|
||||||
|
else
|
||||||
print_server("0x11, 0x08, /* FC_RP [simple_pointer] */\n");
|
print_server("0x11, 0x08, /* FC_RP [simple_pointer] */\n");
|
||||||
print_server("0x%02x, /* FC_<type> */\n", var->type->type);
|
print_server("0x%02x, /* FC_<type> */\n", var->type->type);
|
||||||
print_server("0x5c, /* FC_PAD */\n");
|
print_server("0x5c, /* FC_PAD */\n");
|
||||||
|
@ -208,9 +227,74 @@ static void write_typeformatstring(type_t *iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int get_required_buffer_size(type_t *type)
|
static void print_message_buffer_size(func_t *func)
|
||||||
{
|
{
|
||||||
switch(type->type)
|
unsigned int alignment;
|
||||||
|
int size;
|
||||||
|
int last_size = -1;
|
||||||
|
int in_attr;
|
||||||
|
int out_attr;
|
||||||
|
var_t *var;
|
||||||
|
|
||||||
|
if (func->args)
|
||||||
|
{
|
||||||
|
var = func->args;
|
||||||
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
|
for (; var; var = PREV_LINK(var))
|
||||||
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
if (!out_attr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
alignment = 0;
|
||||||
|
switch (var->type->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_BYTE:
|
||||||
|
case RPC_FC_CHAR:
|
||||||
|
case RPC_FC_SMALL:
|
||||||
|
size = 1;
|
||||||
|
alignment = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_WCHAR:
|
||||||
|
case RPC_FC_USHORT:
|
||||||
|
case RPC_FC_SHORT:
|
||||||
|
size = 2;
|
||||||
|
if (last_size > 0 && last_size < 2)
|
||||||
|
alignment += (2 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_ULONG:
|
||||||
|
case RPC_FC_LONG:
|
||||||
|
case RPC_FC_FLOAT:
|
||||||
|
size = 4;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment += (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_HYPER:
|
||||||
|
case RPC_FC_DOUBLE:
|
||||||
|
size = 8;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment += (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("Unknown/unsupported type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_size != -1)
|
||||||
|
fprintf(server, " +");
|
||||||
|
fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);
|
||||||
|
|
||||||
|
last_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return value size */
|
||||||
|
if (!is_void(func->def->type, NULL))
|
||||||
|
{
|
||||||
|
switch(func->def->type->type)
|
||||||
{
|
{
|
||||||
case RPC_FC_BYTE:
|
case RPC_FC_BYTE:
|
||||||
case RPC_FC_SMALL:
|
case RPC_FC_SMALL:
|
||||||
|
@ -221,18 +305,27 @@ unsigned int get_required_buffer_size(type_t *type)
|
||||||
case RPC_FC_ULONG:
|
case RPC_FC_ULONG:
|
||||||
case RPC_FC_LONG:
|
case RPC_FC_LONG:
|
||||||
case RPC_FC_FLOAT:
|
case RPC_FC_FLOAT:
|
||||||
return 4;
|
size = 4;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
|
alignment += (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
case RPC_FC_HYPER:
|
case RPC_FC_HYPER:
|
||||||
case RPC_FC_DOUBLE:
|
case RPC_FC_DOUBLE:
|
||||||
return 8;
|
size = 8;
|
||||||
|
if (last_size > 0 && last_size < 4)
|
||||||
case RPC_FC_IGNORE:
|
alignment += (4 - last_size);
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error("Unknown/unsupported type: %s\n", type->name);
|
error("Unknown/unsupported type: %s\n", func->def->type->name);
|
||||||
return 0;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_size != -1)
|
||||||
|
fprintf(server, " +");
|
||||||
|
|
||||||
|
fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,20 +359,32 @@ static void init_pointers (func_t *func)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void unmarshall_arguments(func_t *func)
|
static void unmarshall_in_arguments(func_t *func)
|
||||||
{
|
{
|
||||||
unsigned int alignment;
|
unsigned int alignment;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
unsigned int last_size = 0;
|
unsigned int last_size = 0;
|
||||||
var_t *var;
|
var_t *var;
|
||||||
|
int in_attr;
|
||||||
|
int out_attr;
|
||||||
|
|
||||||
if (!func->args)
|
if (!func->args)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var = func->args;
|
var = func->args;
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
while (var)
|
for (; var; var = PREV_LINK(var))
|
||||||
{
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
in_attr = is_attr(var->attrs, ATTR_IN);
|
||||||
|
|
||||||
|
/* set 'in' attribute if neither 'in' nor 'out' is set */
|
||||||
|
if (!out_attr && !in_attr)
|
||||||
|
in_attr = 1;
|
||||||
|
|
||||||
|
if (!in_attr)
|
||||||
|
continue;
|
||||||
|
|
||||||
alignment = 0;
|
alignment = 0;
|
||||||
switch (var->type->type)
|
switch (var->type->type)
|
||||||
{
|
{
|
||||||
|
@ -355,9 +460,160 @@ static void unmarshall_arguments(func_t *func)
|
||||||
|
|
||||||
last_size = size;
|
last_size = size;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void marshall_out_arguments(func_t *func)
|
||||||
|
{
|
||||||
|
unsigned int alignment = 0;
|
||||||
|
unsigned int size = 0;
|
||||||
|
unsigned int last_size = 0;
|
||||||
|
var_t *var;
|
||||||
|
var_t *def;
|
||||||
|
int out_attr;
|
||||||
|
|
||||||
|
def = func->def;
|
||||||
|
|
||||||
|
/* marshall the out arguments */
|
||||||
|
if (func->args)
|
||||||
|
{
|
||||||
|
var = func->args;
|
||||||
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
|
for (; var; var = PREV_LINK(var))
|
||||||
|
{
|
||||||
|
out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
|
if (!out_attr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
alignment = 0;
|
||||||
|
switch (var->type->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_BYTE:
|
||||||
|
case RPC_FC_CHAR:
|
||||||
|
case RPC_FC_SMALL:
|
||||||
|
size = 1;
|
||||||
|
alignment = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_WCHAR:
|
||||||
|
case RPC_FC_USHORT:
|
||||||
|
case RPC_FC_SHORT:
|
||||||
|
size = 2;
|
||||||
|
if (last_size != 0 && last_size < 2)
|
||||||
|
alignment = (2 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_ULONG:
|
||||||
|
case RPC_FC_LONG:
|
||||||
|
case RPC_FC_FLOAT:
|
||||||
|
size = 4;
|
||||||
|
if (last_size != 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_HYPER:
|
||||||
|
case RPC_FC_DOUBLE:
|
||||||
|
size = 8;
|
||||||
|
if (last_size != 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_IGNORE:
|
||||||
|
size = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("Unknown/unsupported type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != 0)
|
||||||
|
{
|
||||||
|
if (alignment != 0)
|
||||||
|
print_server("_StubMsg.Buffer += %u;\n", alignment);
|
||||||
|
|
||||||
|
if (var->ptr_level == 1)
|
||||||
|
{
|
||||||
|
fprintf(server, "\n");
|
||||||
|
print_server("*((");
|
||||||
|
write_type(server, var->type, NULL, var->tname);
|
||||||
|
fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = *");
|
||||||
|
write_name(server, var);
|
||||||
|
fprintf(server, ";\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error("Pointer level %d is not supported!\n", var->ptr_level);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* marshall the return value */
|
||||||
|
if (!is_void(def->type, NULL))
|
||||||
|
{
|
||||||
|
alignment = 0;
|
||||||
|
switch (def->type->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_BYTE:
|
||||||
|
case RPC_FC_CHAR:
|
||||||
|
case RPC_FC_SMALL:
|
||||||
|
case RPC_FC_WCHAR:
|
||||||
|
case RPC_FC_USHORT:
|
||||||
|
case RPC_FC_SHORT:
|
||||||
|
case RPC_FC_ULONG:
|
||||||
|
case RPC_FC_LONG:
|
||||||
|
case RPC_FC_FLOAT:
|
||||||
|
size = 4;
|
||||||
|
if (last_size != 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_FC_HYPER:
|
||||||
|
case RPC_FC_DOUBLE:
|
||||||
|
size = 8;
|
||||||
|
if (last_size != 0 && last_size < 4)
|
||||||
|
alignment = (4 - last_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error("Unknown/unsupported type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(server, "\n");
|
||||||
|
if (alignment != 0)
|
||||||
|
print_server("_StubMsg.Buffer += %u;\n", alignment);
|
||||||
|
print_server("*((");
|
||||||
|
write_type(server, def->type, def, def->tname);
|
||||||
|
fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = _RetVal;\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int use_return_buffer(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);
|
var = PREV_LINK(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,6 +624,9 @@ static void write_function_stubs(type_t *iface)
|
||||||
var_t *var;
|
var_t *var;
|
||||||
var_t* explicit_handle_var;
|
var_t* explicit_handle_var;
|
||||||
unsigned int proc_offset = 0;
|
unsigned int proc_offset = 0;
|
||||||
|
unsigned int i;
|
||||||
|
int in_attr;
|
||||||
|
int out_attr;
|
||||||
|
|
||||||
while (NEXT_LINK(func)) func = NEXT_LINK(func);
|
while (NEXT_LINK(func)) func = NEXT_LINK(func);
|
||||||
while (func)
|
while (func)
|
||||||
|
@ -416,10 +675,23 @@ static void write_function_stubs(type_t *iface)
|
||||||
/* declare arguments */
|
/* declare arguments */
|
||||||
if (func->args)
|
if (func->args)
|
||||||
{
|
{
|
||||||
|
i = 0;
|
||||||
var = func->args;
|
var = func->args;
|
||||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||||
while (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);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
print_server("");
|
print_server("");
|
||||||
write_type(server, var->type, var, var->tname);
|
write_type(server, var->type, var, var->tname);
|
||||||
fprintf(server, " ");
|
fprintf(server, " ");
|
||||||
|
@ -470,7 +742,7 @@ static void write_function_stubs(type_t *iface)
|
||||||
indent -= 2;
|
indent -= 2;
|
||||||
fprintf(server, "\n");
|
fprintf(server, "\n");
|
||||||
|
|
||||||
unmarshall_arguments(func);
|
unmarshall_in_arguments(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
|
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
|
||||||
|
@ -490,6 +762,32 @@ static void write_function_stubs(type_t *iface)
|
||||||
print_server("RpcEndExcept\n");
|
print_server("RpcEndExcept\n");
|
||||||
fprintf(server, "\n");
|
fprintf(server, "\n");
|
||||||
|
|
||||||
|
/* assign out arguments */
|
||||||
|
if (func->args)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
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);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var = PREV_LINK(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
fprintf(server, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Call the real server function */
|
/* Call the real server function */
|
||||||
if (!is_void(def->type, NULL))
|
if (!is_void(def->type, NULL))
|
||||||
|
@ -524,11 +822,13 @@ static void write_function_stubs(type_t *iface)
|
||||||
fprintf(server, "();\n");
|
fprintf(server, "();\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* marshall the return value */
|
/* allocate and fill the return message buffer */
|
||||||
if (!is_void(def->type, NULL))
|
if (use_return_buffer(func))
|
||||||
{
|
{
|
||||||
fprintf(server, "\n");
|
fprintf(server, "\n");
|
||||||
print_server("_StubMsg.BufferLength = %uU;\n", get_required_buffer_size(def->type));
|
print_server("_StubMsg.BufferLength =");
|
||||||
|
print_message_buffer_size(func);
|
||||||
|
fprintf(server, ";\n");
|
||||||
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
|
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
|
||||||
fprintf(server, "\n");
|
fprintf(server, "\n");
|
||||||
print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");
|
print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");
|
||||||
|
@ -538,11 +838,9 @@ static void write_function_stubs(type_t *iface)
|
||||||
indent--;
|
indent--;
|
||||||
fprintf(server, "\n");
|
fprintf(server, "\n");
|
||||||
print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)_pRpcMessage->Buffer;\n");
|
print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)_pRpcMessage->Buffer;\n");
|
||||||
fprintf(server, "\n");
|
|
||||||
|
|
||||||
print_server("*((");
|
/* marshall the out arguments */
|
||||||
write_type(server, def->type, def, def->tname);
|
marshall_out_arguments(func);
|
||||||
fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = _RetVal;\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
indent--;
|
indent--;
|
||||||
|
|
Loading…
Reference in a new issue