Implement [in], [out] and [in, out] support for pointers to basic types. Modified: trunk/reactos/tools/widl/ChangeLog Modified: trunk/reactos/tools/widl/client.c Modified: trunk/reactos/tools/widl/server.c _____
Modified: trunk/reactos/tools/widl/ChangeLog --- trunk/reactos/tools/widl/ChangeLog 2005-03-12 09:40:07 UTC (rev 13965) +++ trunk/reactos/tools/widl/ChangeLog 2005-03-12 13:23:09 UTC (rev 13966) @@ -1,5 +1,13 @@
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
tools/widl/client.c _____
Modified: trunk/reactos/tools/widl/client.c --- trunk/reactos/tools/widl/client.c 2005-03-12 09:40:07 UTC (rev 13965) +++ trunk/reactos/tools/widl/client.c 2005-03-12 13:23:09 UTC (rev 13966) @@ -61,6 +61,7 @@
func_t *func = iface->funcs; var_t *var; unsigned int type_offset = 2; + int in_attr, out_attr;
print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); print_client("{\n"); @@ -79,6 +80,13 @@ while (NEXT_LINK(var)) var = NEXT_LINK(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 (is_base_type(var->type)) @@ -96,7 +104,12 @@ { if (is_base_type(var->type)) { - print_client("0x4d, /* FC_IN_PARAM */\n"); + if (in_attr & !out_attr) + 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"); print_client("0x01,\n"); fprintf(client, "#else\n"); @@ -150,6 +163,7 @@ { func_t *func = iface->funcs; var_t *var; + int out_attr;
print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); print_client("{\n"); @@ -168,6 +182,8 @@ while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (var->ptr_level > 1) { error("Function '%s' argument '%s': Pointer level %d not supported!\n", @@ -179,7 +195,10 @@ { if (is_base_type(var->type)) { - print_client("0x11, 0x08, /* FC_RP [simple_pointer] */\n"); + 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("0x%02x, /* FC_<type> */\n", var->type->type); print_client("0x5c, /* FC_PAD */\n"); } @@ -210,75 +229,80 @@ int last_size = -1; int in_attr; int out_attr; + int nothing_printed = 1; var_t *var;
- if (!func->args) + if (func->args) { - fprintf(client, " 0U"); - return; - } + 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); + in_attr = is_attr(var->attrs, ATTR_IN);
- 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); - in_attr = is_attr(var->attrs, ATTR_IN); + /* set 'in' attribute if neither 'in' nor 'out' is found */ + if (!out_attr && !in_attr) + in_attr = 1;
- /* set 'in' attribute if neither 'in' nor 'out' is found */ - if (!out_attr && !in_attr) - in_attr = 1; + if (!in_attr) + continue;
- if (!in_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; + 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_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_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_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; + case RPC_FC_IGNORE: + size = 0; + break;
- default: - error("Unknown/unsupported type!"); - } + default: + error("Unknown/unsupported type!"); + return; + }
- if (last_size != -1) - fprintf(client, " +"); - fprintf(client, " %dU", (size == 0) ? 0 : size + alignment); + if (last_size != -1) + fprintf(client, " +"); + fprintf(client, " %dU", (size == 0) ? 0 : size + alignment); + nothing_printed = 0;
- last_size = size; + last_size = size; + } } + + if (nothing_printed) + { + fprintf(client, " 0U"); + } }
@@ -376,6 +400,137 @@ }
+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) { var_t *var; @@ -408,6 +563,30 @@ }
+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) { char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); @@ -523,11 +702,10 @@ print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n"); indent--;
- /* convert data representation */ - if (!is_void(def->type, NULL)) + if (use_return_buffer(func)) { + /* convert data representation */ fprintf(client, "\n"); - print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_client("NdrConvert(\n"); @@ -535,11 +713,9 @@ print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset); indent -= 2; - fprintf(client, "\n");
- print_client("_RetVal = *(("); - write_type(client, def->type, def, def->tname); - fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n"); + /* unmarshal out arguments */ + unmarshall_out_arguments(func); }
/* update proc_offset */ _____
Modified: trunk/reactos/tools/widl/server.c --- trunk/reactos/tools/widl/server.c 2005-03-12 09:40:07 UTC (rev 13965) +++ trunk/reactos/tools/widl/server.c 2005-03-12 13:23:09 UTC (rev 13966) @@ -66,6 +66,7 @@
func_t *func = iface->funcs; var_t *var; unsigned int type_offset = 2; + int in_attr, out_attr;
print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); print_server("{\n"); @@ -84,6 +85,13 @@ while (NEXT_LINK(var)) var = NEXT_LINK(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 (is_base_type(var->type)) @@ -101,7 +109,12 @@ { if (is_base_type(var->type)) { - print_server("0x4d, /* FC_IN_PARAM */\n"); + if (in_attr & !out_attr) + 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"); print_server("0x01,\n"); fprintf(server, "#else\n"); @@ -155,6 +168,7 @@ { func_t *func = iface->funcs; var_t *var; + int out_attr;
print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); print_server("{\n"); @@ -173,6 +187,8 @@ while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (var->ptr_level > 1) { error("Function '%s' argument '%s': Pointer level %d not supported!\n", @@ -184,7 +200,10 @@ { if (is_base_type(var->type)) { - print_server("0x11, 0x08, /* FC_RP [simple_pointer] */\n"); + 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("0x%02x, /* FC_<type> */\n", var->type->type); print_server("0x5c, /* FC_PAD */\n"); } @@ -208,10 +227,75 @@ }
-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_SMALL: case RPC_FC_CHAR: @@ -221,18 +305,27 @@ case RPC_FC_ULONG: case RPC_FC_LONG: 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_DOUBLE: - return 8; + size = 8; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break;
- case RPC_FC_IGNORE: - return 0; + default: + error("Unknown/unsupported type: %s\n", func->def->type->name); + return; + }
- default: - error("Unknown/unsupported type: %s\n", type->name); - return 0; + if (last_size != -1) + fprintf(server, " +"); + + fprintf(server, " %dU", (size == 0) ? 0 : size + alignment); } }
@@ -266,20 +359,32 @@ }
-static void unmarshall_arguments(func_t *func) +static void unmarshall_in_arguments(func_t *func) { unsigned int alignment; unsigned int size; unsigned int last_size = 0; var_t *var; + int in_attr; + int out_attr;
if (!func->args) return;
var = func->args; 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; switch (var->type->type) { @@ -355,9 +460,160 @@
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); } + + return 0; }
@@ -368,6 +624,9 @@ var_t *var; var_t* explicit_handle_var; unsigned int proc_offset = 0; + unsigned int i; + int in_attr; + int out_attr;
while (NEXT_LINK(func)) func = NEXT_LINK(func); while (func) @@ -416,10 +675,23 @@ /* declare 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_type(server, var->type, NULL, var->tname); + fprintf(server, " _W%u;\n", i); + i++; + } + print_server(""); write_type(server, var->type, var, var->tname); fprintf(server, " "); @@ -470,7 +742,7 @@ indent -= 2; fprintf(server, "\n");
- unmarshall_arguments(func); + unmarshall_in_arguments(func); }
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); @@ -490,7 +762,33 @@ print_server("RpcEndExcept\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 */ if (!is_void(def->type, NULL)) print_server("_RetVal = "); @@ -524,11 +822,13 @@ fprintf(server, "();\n"); }
- /* marshall the return value */ - if (!is_void(def->type, NULL)) + /* allocate and fill the return message buffer */ + if (use_return_buffer(func)) { 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"); fprintf(server, "\n"); print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n"); @@ -538,11 +838,9 @@ indent--; fprintf(server, "\n"); print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)_pRpcMessage->Buffer;\n"); - fprintf(server, "\n");
- print_server("*(("); - write_type(server, def->type, def, def->tname); - fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = _RetVal;\n"); + /* marshall the out arguments */ + marshall_out_arguments(func); }
indent--;