tools/widl
Ge van Geldorp
gvg at reactos.com
Mon Apr 25 06:57:52 CDT 2005
Changelog:
Eric Kohl <eric.kohl at t-online.de>
- WIDL: Support basic type function arguments.
- Support remaining basic types (float, double, small, wchar_t and handle_t).
Index: include/wine/rpcfc.h
===================================================================
RCS file: /home/wine/wine/include/wine/rpcfc.h,v
retrieving revision 1.7
diff -u -r1.7 rpcfc.h
--- include/wine/rpcfc.h 2 Mar 2005 12:23:21 -0000 1.7
+++ include/wine/rpcfc.h 25 Apr 2005 11:53:04 -0000
@@ -21,7 +21,7 @@
#define RPC_FC_DOUBLE 0x0c
#define RPC_FC_ENUM16 0x0d
#define RPC_FC_ENUM32 0x0e
-
+#define RPC_FC_IGNORE 0x0f /* handle_t */
#define RPC_FC_ERROR_STATUS_T 0x10
/* other stuff */
Index: tools/widl/client.c
===================================================================
RCS file: /home/wine/wine/tools/widl/client.c,v
retrieving revision 1.4
diff -u -r1.4 client.c
--- tools/widl/client.c 15 Apr 2005 14:09:45 -0000 1.4
+++ tools/widl/client.c 25 Apr 2005 11:53:04 -0000
@@ -67,7 +67,8 @@
static void write_procformatstring(type_t *iface)
{
- func_t *cur = iface->funcs;
+ func_t *func = iface->funcs;
+ var_t *var;
print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
print_client("{\n");
@@ -76,23 +77,131 @@
print_client("{\n");
indent++;
- while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
- while (cur)
+ while (NEXT_LINK(func)) func = NEXT_LINK(func);
+ while (func)
{
- var_t *def = cur->def;
+ /* emit argument data */
+ if (func->args)
+ {
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ switch(var->type->type)
+ {
+ case RPC_FC_BYTE:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_BYTE */\n", RPC_FC_BYTE);
+ break;
+ case RPC_FC_CHAR:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_CHAR */\n", RPC_FC_CHAR);
+ break;
+ case RPC_FC_WCHAR:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_WCHAR */\n", RPC_FC_WCHAR);
+ break;
+ case RPC_FC_USHORT:
+ case RPC_FC_SHORT:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_USHORT */\n", RPC_FC_SHORT);
+ break;
+ case RPC_FC_ULONG:
+ case RPC_FC_LONG:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_LONG */\n", RPC_FC_LONG);
+ break;
+ case RPC_FC_HYPER:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_HYPER */\n", RPC_FC_HYPER);
+ break;
+ case RPC_FC_IGNORE:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE);
+ break;
+ case RPC_FC_SMALL:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_SMALL */\n", RPC_FC_SMALL);
+ break;
+ case RPC_FC_FLOAT:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_FLOAT */\n", RPC_FC_FLOAT);
+ break;
+ case RPC_FC_DOUBLE:
+ print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_DOUBLE */\n", RPC_FC_DOUBLE);
+ break;
+ default:
+ error("Unknown/unsupported type\n");
+ return;
+ }
+
+ var = PREV_LINK(var);
+ }
+ }
- if (is_void(def->type, NULL))
+ /* emit return value data */
+ var = func->def;
+ if (is_void(var->type, NULL))
{
print_client("0x5b, /* FC_END */\n");
print_client("0x5c, /* FC_PAD */\n");
}
else
{
- print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
- print_client("0x%02x, /* <type> */\n", def->type->type);
+ switch(var->type->type)
+ {
+ case RPC_FC_BYTE:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_BYTE */\n", var->type->type);
+ break;
+ case RPC_FC_CHAR:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_CHAR */\n", var->type->type);
+ break;
+ case RPC_FC_WCHAR:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_WCHAR */\n", var->type->type);
+ break;
+ case RPC_FC_USHORT:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_USHORT */\n", var->type->type);
+ break;
+ case RPC_FC_SHORT:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_SHORT */\n", var->type->type);
+ break;
+ case RPC_FC_ULONG:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_ULONG */\n", var->type->type);
+ break;
+ case RPC_FC_LONG:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_LONG */\n", var->type->type);
+ break;
+ case RPC_FC_HYPER:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_HYPER */\n", var->type->type);
+ break;
+ case RPC_FC_SMALL:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_SMALL */\n", RPC_FC_SMALL);
+ break;
+ case RPC_FC_FLOAT:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_FLOAT */\n", RPC_FC_FLOAT);
+ break;
+ case RPC_FC_DOUBLE:
+ print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_client("0x%02x, /* FC_DOUBLE */\n", RPC_FC_DOUBLE);
+ break;
+ default:
+ error("Unknown/unsupported type\n");
+ return;
+ }
}
- cur = PREV_LINK(cur);
+ func = PREV_LINK(func);
}
print_client("0x0\n");
@@ -122,27 +231,180 @@
}
+static void print_message_buffer_size(func_t *func)
+{
+ unsigned int alignment;
+ unsigned int size;
+ unsigned int last_size = 0;
+ var_t *var;
+
+ if (!func->args)
+ {
+ fprintf(client, " 0U");
+ return;
+ }
+
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ 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 (last_size != 0)
+ fprintf(client, " +");
+ fprintf(client, " 0U");
+ }
+ else
+ {
+ if (last_size != 0)
+ fprintf(client, " +");
+ fprintf(client, " %uU", size + alignment);
+
+ last_size = size;
+ }
+
+
+ var = PREV_LINK(var);
+ }
+}
+
+
+static void marshall_arguments(func_t *func)
+{
+ unsigned int alignment;
+ unsigned int size;
+ unsigned int last_size = 0;
+ var_t *var;
+
+ if (!func->args)
+ return;
+
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ 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_client("_StubMsg.Buffer += %u;\n", alignment);
+
+ print_client("*((");
+ write_type(client, var->type, var, var->tname);
+ fprintf(client, " __RPC_FAR*)_StubMsg.Buffer)++ = ");
+ write_name(client, var);
+ fprintf(client, ";\n");
+ fprintf(client, "\n");
+
+ last_size = size;
+ }
+
+ var = PREV_LINK(var);
+ }
+}
+
+
static void write_function_stubs(type_t *iface)
{
- func_t *cur = iface->funcs;
- char *handle_name = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ int explitit_handle = is_attr(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ func_t *func = iface->funcs;
+ var_t* var;
int method_count = 0;
unsigned int proc_offset = 0;
- while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
- while (cur)
+ while (NEXT_LINK(func)) func = NEXT_LINK(func);
+ while (func)
{
- var_t *def = cur->def;
+ var_t *def = func->def;
write_type(client, def->type, def, def->tname);
fprintf(client, " ");
write_name(client, def);
fprintf(client, "(\n");
indent++;
- if (cur->args)
- write_args(client, cur->args, iface->name, 0, TRUE);
- else
- print_client("void");
+ write_args(client, func->args, iface->name, 0, TRUE);
fprintf(client, ")\n");
indent--;
@@ -158,9 +420,8 @@
fprintf(client, " _RetVal;\n");
}
- if (handle_name)
+ if (implicit_handle)
print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
-
print_client("RPC_MESSAGE _RpcMessage;\n");
print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
fprintf(client, "\n");
@@ -177,17 +438,23 @@
indent--;
fprintf(client, "\n");
- if (handle_name)
- print_client("_Handle = %s;\n", handle_name);
+ if (implicit_handle)
+ {
+ print_client("_Handle = %s;\n", implicit_handle);
+ fprintf(client, "\n");
+ }
+
+ /* emit the message buffer size */
+ print_client("_StubMsg.BufferLength =");
+ print_message_buffer_size(func);
+ fprintf(client, ";\n");
+
- /* FIXME: marshal arguments */
- print_client("_StubMsg.BufferLength = 0UL;\n");
- /* print_client("NdrNsGetBuffer(\n"); */
print_client("NdrGetBuffer(\n");
indent++;
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_client("_StubMsg.BufferLength,\n");
- if (handle_name)
+ if (implicit_handle)
print_client("%_Handle);\n");
else
print_client("%s__MIDL_AutoBindHandle);\n", iface->name);
@@ -196,21 +463,14 @@
/* send/receive message */
- /* print_client("NdrNsSendReceive(\n"); */
print_client("NdrSendReceive(\n");
indent++;
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");
- /* print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer,\n"); */
- /* print_client("(RPC_BINDING_HANDLE __RPC_FAR *) &%s__MIDL_AutoBindHandle);\n", iface->name); */
indent--;
/* unmarshal return value */
- if (is_void(def->type, NULL))
- {
- proc_offset += 2;
- }
- else
+ if (!is_void(def->type, NULL))
{
fprintf(client, "\n");
@@ -219,17 +479,27 @@
print_client("NdrConvert(\n");
indent++;
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
- print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString[%u]);\n", proc_offset);
+ 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");
+ }
- /* FIXME: update proc_offset */
- proc_offset += 2;
+ /* update proc_offset */
+ if (func->args)
+ {
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ proc_offset += 2; /* FIXME */
+ var = PREV_LINK(var);
+ }
}
+ proc_offset += 2; /* FIXME */
indent--;
print_client("}\n");
@@ -259,7 +529,7 @@
fprintf(client, "\n");
method_count++;
- cur = PREV_LINK(cur);
+ func = PREV_LINK(func);
}
}
@@ -280,7 +550,7 @@
static void write_stubdescriptor(type_t *iface)
{
- char *handle_name = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name);
print_client("{\n");
@@ -288,8 +558,8 @@
print_client("(void __RPC_FAR *)& %s___RpcClientInterface,\n", iface->name);
print_client("MIDL_user_allocate,\n");
print_client("MIDL_user_free,\n");
- if (handle_name)
- print_client("&%s,\n", handle_name);
+ if (implicit_handle)
+ print_client("&%s,\n", implicit_handle);
else
print_client("&%s__MIDL_AutoBindHandle,\n", iface->name);
print_client("0,\n");
@@ -357,19 +627,34 @@
static void write_formatstringsdecl(type_t *iface)
{
- func_t *cur;
int byte_count = 1;
+ func_t *func;
+ var_t *var;
print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */
/* determine the proc format string size */
- cur = iface->funcs;
- while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
- while (cur)
+ func = iface->funcs;
+ while (NEXT_LINK(func)) func = NEXT_LINK(func);
+ while (func)
{
+ /* argument list size */
+ if (func->args)
+ {
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ byte_count += 2; /* FIXME: determine real size */
+ var = PREV_LINK(var);
+ }
+ }
+
+ /* return value size */
byte_count += 2; /* FIXME: determine real size */
- cur = PREV_LINK(cur);
+ func = PREV_LINK(func);
}
+
print_client("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);
fprintf(client, "\n");
@@ -384,11 +669,11 @@
static void write_implicithandledecl(type_t *iface)
{
- char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
- if (var)
+ if (implicit_handle)
{
- fprintf(client, "handle_t %s;\n", var);
+ fprintf(client, "handle_t %s;\n", implicit_handle);
fprintf(client, "\n");
}
}
Index: tools/widl/header.c
===================================================================
RCS file: /home/wine/wine/tools/widl/header.c,v
retrieving revision 1.34
diff -u -r1.34 header.c
--- tools/widl/header.c 5 Mar 2005 10:49:22 -0000 1.34
+++ tools/widl/header.c 25 Apr 2005 11:53:05 -0000
@@ -256,7 +256,7 @@
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "error_status_t");
break;
- case RPC_FC_BIND_PRIMITIVE:
+ case RPC_FC_IGNORE:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "handle_t");
break;
@@ -529,6 +529,10 @@
fprintf(h, "%s* This", name);
count++;
}
+ if (arg == NULL && method == 0) {
+ fprintf(h, "void");
+ return;
+ }
while (arg) {
if (count) {
if (do_indent)
@@ -686,10 +690,7 @@
fprintf(header, " ");
write_name(header, def);
fprintf(header, "(\n");
- if (cur->args)
- write_args(header, cur->args, iface->name, 0, TRUE);
- else
- fprintf(header, " void");
+ write_args(header, cur->args, iface->name, 0, TRUE);
fprintf(header, ");\n");
cur = PREV_LINK(cur);
Index: tools/widl/parser.l
===================================================================
RCS file: /home/wine/wine/tools/widl/parser.l,v
retrieving revision 1.28
diff -u -r1.28 parser.l
--- tools/widl/parser.l 28 Mar 2005 10:01:13 -0000 1.28
+++ tools/widl/parser.l 25 Apr 2005 11:53:05 -0000
@@ -289,6 +289,7 @@
{"size_is", tSIZEIS},
{"sizeof", tSIZEOF},
/* ... */
+ {"small", tSMALL},
{"source", tSOURCE},
/* ... */
{"string", tSTRING},
Index: tools/widl/parser.y
===================================================================
RCS file: /home/wine/wine/tools/widl/parser.y,v
retrieving revision 1.45
diff -u -r1.45 parser.y
--- tools/widl/parser.y 28 Mar 2005 10:01:13 -0000 1.45
+++ tools/widl/parser.y 25 Apr 2005 11:53:05 -0000
@@ -172,6 +172,7 @@
%token tSIGNED
%token tSINGLE
%token tSIZEIS tSIZEOF
+%token tSMALL
%token tSOURCE
%token tSTDCALL
%token tSTRING tSTRUCT
@@ -554,7 +555,7 @@
| tSIGNED int_std { $$ = $2; $$->sign = 1; }
| tUNSIGNED int_std { $$ = $2; $$->sign = -1;
switch ($$->type) {
- case RPC_FC_CHAR: $$->type = RPC_FC_BYTE; $$->sign = 0; break;
+ case RPC_FC_CHAR: break;
case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break;
case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break;
case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break;
@@ -568,9 +569,9 @@
| tFLOAT { $$ = make_type(RPC_FC_FLOAT, NULL); }
| tSINGLE { $$ = make_type(RPC_FC_FLOAT, NULL); }
| tDOUBLE { $$ = make_type(RPC_FC_DOUBLE, NULL); }
- | tBOOLEAN { $$ = make_type(RPC_FC_BYTE, &std_bool); /* ? */ }
+ | tBOOLEAN { $$ = make_type(RPC_FC_SMALL, &std_bool); }
| tERRORSTATUST { $$ = make_type(RPC_FC_ERROR_STATUS_T, NULL); }
- | tHANDLET { $$ = make_type(RPC_FC_BIND_PRIMITIVE, NULL); /* ? */ }
+ | tHANDLET { $$ = make_type(RPC_FC_IGNORE, NULL); }
;
m_int:
@@ -578,6 +579,7 @@
;
int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */
+ | tSMALL m_int { $$ = make_type(RPC_FC_SMALL, NULL); }
| tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); }
| tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); }
| tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); }
Index: tools/widl/server.c
===================================================================
RCS file: /home/wine/wine/tools/widl/server.c,v
retrieving revision 1.3
diff -u -r1.3 server.c
--- tools/widl/server.c 15 Apr 2005 14:09:45 -0000 1.3
+++ tools/widl/server.c 25 Apr 2005 11:53:06 -0000
@@ -69,7 +69,8 @@
static void write_procformatstring(type_t *iface)
{
- func_t *cur = iface->funcs;
+ func_t *func = iface->funcs;
+ var_t *var;
print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
print_server("{\n");
@@ -78,23 +79,135 @@
print_server("{\n");
indent++;
- while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
- while (cur)
+ while (NEXT_LINK(func)) func = NEXT_LINK(func);
+ while (func)
{
- var_t *def = cur->def;
+ /* emit argument data */
+ if (func->args)
+ {
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ switch(var->type->type)
+ {
+ case RPC_FC_BYTE:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_BYTE */\n", var->type->type);
+ break;
+ case RPC_FC_CHAR:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_CHAR */\n", var->type->type);
+ break;
+ case RPC_FC_WCHAR:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_WCHAR */\n", var->type->type);
+ break;
+ case RPC_FC_USHORT:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_USHORT */\n", var->type->type);
+ break;
+ case RPC_FC_SHORT:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_SHORT */\n", var->type->type);
+ break;
+ case RPC_FC_ULONG:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_ULONG */\n", var->type->type);
+ break;
+ case RPC_FC_LONG:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_LONG */\n", var->type->type);
+ break;
+ case RPC_FC_HYPER:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_HYPER */\n", var->type->type);
+ break;
+ case RPC_FC_IGNORE:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_IGNORE */\n", var->type->type);
+ break;
+ case RPC_FC_SMALL:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_SMALL */\n", RPC_FC_SMALL);
+ break;
+ case RPC_FC_FLOAT:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_FLOAT */\n", RPC_FC_FLOAT);
+ break;
+ case RPC_FC_DOUBLE:
+ print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_DOUBLE */\n", RPC_FC_DOUBLE);
+ break;
+ default:
+ error("Unknown/unsupported type\n");
+ }
- if (is_void(def->type, NULL))
+ var = PREV_LINK(var);
+ }
+ }
+
+ /* emit return value data */
+ var = func->def;
+ if (is_void(var->type, NULL))
{
print_server("0x5b, /* FC_END */\n");
print_server("0x5c, /* FC_PAD */\n");
}
else
{
- print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
- print_server("0x%02x, /* <type> */\n", def->type->type);
+ switch(var->type->type)
+ {
+ case RPC_FC_BYTE:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_BYTE */\n", var->type->type);
+ break;
+ case RPC_FC_CHAR:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_CHAR */\n", var->type->type);
+ break;
+ case RPC_FC_WCHAR:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_WCHAR */\n", var->type->type);
+ break;
+ case RPC_FC_USHORT:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_USHORT */\n", var->type->type);
+ break;
+ case RPC_FC_SHORT:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_SHORT */\n", var->type->type);
+ break;
+ case RPC_FC_ULONG:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_ULONG */\n", var->type->type);
+ break;
+ case RPC_FC_LONG:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_LONG */\n", var->type->type);
+ break;
+ case RPC_FC_HYPER:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_HYPER */\n", var->type->type);
+ break;
+ case RPC_FC_SMALL:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_SMALL */\n", RPC_FC_SMALL);
+ break;
+ case RPC_FC_FLOAT:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_FLOAT */\n", RPC_FC_FLOAT);
+ break;
+ case RPC_FC_DOUBLE:
+ print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
+ print_server("0x%02x, /* FC_DOUBLE */\n", RPC_FC_DOUBLE);
+ break;
+ default:
+ error("Unknown/unsupported type\n");
+ }
}
- cur = PREV_LINK(cur);
+ func = PREV_LINK(func);
}
print_server("0x0\n");
@@ -124,22 +237,28 @@
}
-unsigned int get_required_stack_size(type_t *type)
+unsigned int get_required_buffer_size(type_t *type)
{
switch(type->type)
{
case RPC_FC_BYTE:
+ case RPC_FC_SMALL:
case RPC_FC_CHAR:
case RPC_FC_WCHAR:
case RPC_FC_USHORT:
case RPC_FC_SHORT:
case RPC_FC_ULONG:
case RPC_FC_LONG:
+ case RPC_FC_FLOAT:
return 4;
- case RPC_FC_HYPER:
+ case RPC_FC_HYPER:
+ case RPC_FC_DOUBLE:
return 8;
+ case RPC_FC_IGNORE:
+ return 0;
+
default:
error("Unknown/unsupported type: %s\n", type->name);
return 0;
@@ -147,13 +266,91 @@
}
+static void unmarshall_arguments(func_t *func)
+{
+ unsigned int alignment;
+ unsigned int size;
+ unsigned int last_size = 0;
+ var_t *var;
+
+ if (!func->args)
+ return;
+
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ 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);
+
+ print_server("");
+ write_name(server, var);
+ fprintf(server, " = *((");
+ write_type(server, var->type, var, var->tname);
+ fprintf(server, " __RPC_FAR*)_StubMsg.Buffer)++;\n");
+ fprintf(server, "\n");
+
+ last_size = size;
+ }
+
+ var = PREV_LINK(var);
+ }
+}
+
+
static void write_function_stubs(type_t *iface)
{
- func_t *cur = iface->funcs;
- while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
- while (cur)
+ func_t *func = iface->funcs;
+ var_t *var;
+ unsigned int proc_offset = 0;
+
+ while (NEXT_LINK(func)) func = NEXT_LINK(func);
+ while (func)
{
- var_t *def = cur->def;
+ var_t *def = func->def;
write_type(server, def->type, def, def->tname);
fprintf(server, " __RPC_STUB\n");
@@ -176,9 +373,28 @@
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);
+ fprintf(server, ";\n");
+
+ var = PREV_LINK(var);
+ }
+ }
+
print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
print_server("RPC_STATUS _Status;\n");
fprintf(server, "\n");
+
+
print_server("((void)(_Status));\n");
print_server("NdrServerInitializeNew(\n");
indent++;
@@ -194,6 +410,21 @@
print_server("RpcTryExcept\n");
print_server("{\n");
indent++;
+
+ if (func->args)
+ {
+ print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
+ indent++;
+ print_server("NdrConvert(\n");
+ indent++;
+ print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+ print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);
+ indent -= 2;
+ fprintf(server, "\n");
+
+ unmarshall_arguments(func);
+ }
+
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
print_server("{\n");
indent++;
@@ -219,14 +450,37 @@
print_server("");
write_name(server, def);
- /* FIXME: handle argument list */
- fprintf(server, "();\n");
+ if (func->args)
+ {
+ int first_arg = 1;
- /* FIXME: Marshall the return value */
+ fprintf(server, "(\n");
+ indent++;
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ if (first_arg)
+ first_arg = 0;
+ else
+ fprintf(server, ",\n");
+ print_server("");
+ write_name(server, var);
+ var = PREV_LINK(var);
+ }
+ fprintf(server, ");\n");
+ indent--;
+ }
+ else
+ {
+ fprintf(server, "();\n");
+ }
+
+ /* marshall the return value */
if (!is_void(def->type, NULL))
{
fprintf(server, "\n");
- print_server("_StubMsg.BufferLength = %uU;\n", get_required_stack_size(def->type));
+ print_server("_StubMsg.BufferLength = %uU;\n", get_required_buffer_size(def->type));
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
fprintf(server, "\n");
print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");
@@ -260,7 +514,20 @@
fprintf(server, "}\n");
fprintf(server, "\n");
- cur = PREV_LINK(cur);
+ /* update proc_offset */
+ if (func->args)
+ {
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ proc_offset += 2; /* FIXME */
+ var = PREV_LINK(var);
+ }
+ }
+ proc_offset += 2; /* FIXME */
+
+ func = PREV_LINK(func);
}
}
@@ -382,18 +649,32 @@
static void write_formatstringsdecl(type_t *iface)
{
- func_t *cur;
+ func_t *func;
+ var_t *var;
int byte_count = 1;
print_server("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */
/* determine the proc format string size */
- cur = iface->funcs;
- while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
- while (cur)
+ func = iface->funcs;
+ while (NEXT_LINK(func)) func = NEXT_LINK(func);
+ while (func)
{
+ /* argument list size */
+ if (func->args)
+ {
+ var = func->args;
+ while (NEXT_LINK(var)) var = NEXT_LINK(var);
+ while (var)
+ {
+ byte_count += 2; /* FIXME: determine real size */
+ var = PREV_LINK(var);
+ }
+ }
+
+ /* return value size */
byte_count += 2; /* FIXME: determine real size */
- cur = PREV_LINK(cur);
+ func = PREV_LINK(func);
}
print_server("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);
More information about the wine-patches
mailing list