WIDL: Support basic type function arguments.
authorEric Kohl <eric.kohl@reactos.org>
Wed, 23 Feb 2005 13:15:40 +0000 (13:15 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Wed, 23 Feb 2005 13:15:40 +0000 (13:15 +0000)
svn path=/trunk/; revision=13725

reactos/tools/widl/client.c
reactos/tools/widl/server.c

index 9dfcf76..1be77f6 100644 (file)
@@ -58,7 +58,8 @@ static int print_client( const char *format, ... )
 \r
 static void write_procformatstring(type_t *iface)\r
 {\r
 \r
 static void write_procformatstring(type_t *iface)\r
 {\r
-    func_t *cur = iface->funcs;\r
+    func_t *func = iface->funcs;\r
+    var_t *var;\r
 \r
     print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");\r
     print_client("{\n");\r
 \r
     print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");\r
     print_client("{\n");\r
@@ -67,23 +68,107 @@ static void write_procformatstring(type_t *iface)
     print_client("{\n");\r
     indent++;\r
 \r
     print_client("{\n");\r
     indent++;\r
 \r
-    while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);\r
-    while (cur)\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
     {\r
     {\r
-        var_t *def = cur->def;\r
+        /* emit argument data */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                switch(var->type->type)\r
+                {\r
+                case RPC_FC_BYTE:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_BYTE */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_CHAR:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_CHAR */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_WCHAR:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_WCHAR */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_USHORT:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_USHORT */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_SHORT:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_SHORT */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_ULONG:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_ULONG */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_LONG:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_LONG */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_HYPER:\r
+                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_client("0x%02x,    /* RPC_FC_HYPER */\n", var->type->type);\r
+                    break;\r
+                default:\r
+                    error("Unknown/unsupported type\n");\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
 \r
 \r
-        if (is_void(def->type, NULL))\r
+        /* emit return value data */\r
+        var = func->def;\r
+        if (is_void(var->type, NULL))\r
         {\r
             print_client("0x5b,    /* FC_END */\n");\r
             print_client("0x5c,    /* FC_PAD */\n");\r
         }\r
         else\r
         {\r
         {\r
             print_client("0x5b,    /* FC_END */\n");\r
             print_client("0x5c,    /* FC_PAD */\n");\r
         }\r
         else\r
         {\r
-            print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-            print_client("0x%02x,    /* <type> */\n", def->type->type);\r
+            switch(var->type->type)\r
+            {\r
+            case RPC_FC_BYTE:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_BYTE */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_CHAR:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_CHAR */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_WCHAR:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_WCHAR */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_USHORT:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_USHORT */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_SHORT:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_SHORT */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_ULONG:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_ULONG */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_LONG:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_LONG */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_HYPER:\r
+                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_client("0x%02x,    /* RPC_FC_HYPER */\n", var->type->type);\r
+                break;\r
+            default:\r
+                error("Unknown/unsupported type\n");\r
+            }\r
         }\r
 \r
         }\r
 \r
-        cur = PREV_LINK(cur);\r
+        func = PREV_LINK(func);\r
     }\r
 \r
     print_client("0x0\n");\r
     }\r
 \r
     print_client("0x0\n");\r
@@ -113,25 +198,153 @@ static void write_typeformatstring(void)
 }\r
 \r
 \r
 }\r
 \r
 \r
+static void print_message_buffer_size(func_t *func)\r
+{\r
+    unsigned int alignment;\r
+    unsigned int size;\r
+    unsigned int last_size = 0;\r
+    var_t *var;\r
+\r
+    if (!func->args)\r
+    {\r
+        fprintf(client, " 0U");\r
+        return;\r
+    }\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        alignment = 0;\r
+        switch (var->type->type)\r
+        {\r
+        case RPC_FC_BYTE:\r
+        case RPC_FC_CHAR:\r
+            size = 1;\r
+            alignment = 0;\r
+            break;\r
+\r
+        case RPC_FC_WCHAR:\r
+        case RPC_FC_USHORT:\r
+        case RPC_FC_SHORT:\r
+            size = 2;\r
+            if (last_size != 0 && last_size < 2)\r
+                alignment += (2 - last_size);\r
+            break;\r
+\r
+        case RPC_FC_ULONG:\r
+        case RPC_FC_LONG:\r
+            size = 4;\r
+            if (last_size != 0 && last_size < 4)\r
+                alignment += (4 - last_size);\r
+            break;\r
+\r
+        case RPC_FC_HYPER:\r
+            size = 8;\r
+            if (last_size != 0 && last_size < 4)\r
+                alignment += (4 - last_size);\r
+            break;\r
+\r
+        default:\r
+            error("Unknown/unsupported type!");\r
+        }\r
+\r
+        if (last_size != 0)\r
+            fprintf(client, " +");\r
+        fprintf(client, " %uU", size + alignment);\r
+\r
+        last_size = size;\r
+\r
+        var = PREV_LINK(var);\r
+    }\r
+}\r
+\r
+\r
+static void marshall_arguments(func_t *func)\r
+{\r
+    unsigned int alignment;\r
+    unsigned int size;\r
+    unsigned int last_size = 0;\r
+    var_t *var;\r
+\r
+    if (!func->args)\r
+        return;\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        alignment = 0;\r
+        switch (var->type->type)\r
+        {\r
+        case RPC_FC_BYTE:\r
+        case RPC_FC_CHAR:\r
+            size = 1;\r
+            alignment = 0;\r
+            break;\r
+\r
+        case RPC_FC_WCHAR:\r
+        case RPC_FC_USHORT:\r
+        case RPC_FC_SHORT:\r
+            size = 2;\r
+            if (last_size != 0 && last_size < 2)\r
+                alignment = (2 - last_size);\r
+            break;\r
+\r
+        case RPC_FC_ULONG:\r
+        case RPC_FC_LONG:\r
+            size = 4;\r
+            if (last_size != 0 && last_size < 4)\r
+                alignment = (4 - last_size);\r
+            break;\r
+\r
+        case RPC_FC_HYPER:\r
+            size = 8;\r
+            if (last_size != 0 && last_size < 4)\r
+                alignment = (4 - last_size);\r
+            break;\r
+\r
+        default:\r
+            error("Unknown/unsupported type!");\r
+        }\r
+\r
+        if (alignment != 0)\r
+            print_client("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+        print_client("*((");\r
+        write_type(client, var->type, var, var->tname);\r
+        fprintf(client, " __RPC_FAR*)_StubMsg.Buffer)++ = ");\r
+        write_name(client, var);\r
+        fprintf(client, ";\n");\r
+        fprintf(client, "\n");\r
+\r
+        last_size = size;\r
+\r
+        var = PREV_LINK(var);\r
+    }\r
+}\r
+\r
+\r
 static void write_function_stubs(type_t *iface)\r
 {\r
 static void write_function_stubs(type_t *iface)\r
 {\r
-    func_t *cur = iface->funcs;\r
-    char *handle_name = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
+    char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
+    func_t *func = iface->funcs;\r
+    var_t* var;\r
     int method_count = 0;\r
     unsigned int proc_offset = 0;\r
 \r
     int method_count = 0;\r
     unsigned int proc_offset = 0;\r
 \r
-    while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);\r
-    while (cur)\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
     {\r
     {\r
-        var_t *def = cur->def;\r
+        var_t *def = func->def;\r
 \r
         write_type(client, def->type, def, def->tname);\r
         fprintf(client, " ");\r
         write_name(client, def);\r
         fprintf(client, "(\n");\r
         indent++;\r
 \r
         write_type(client, def->type, def, def->tname);\r
         fprintf(client, " ");\r
         write_name(client, def);\r
         fprintf(client, "(\n");\r
         indent++;\r
-        if (cur->args)\r
-            write_args(client, cur->args, iface->name, 0, TRUE);\r
+        if (func->args)\r
+            write_args(client, func->args, iface->name, 0, TRUE);\r
         else\r
             print_client("void");\r
         fprintf(client, ")\n");\r
         else\r
             print_client("void");\r
         fprintf(client, ")\n");\r
@@ -149,9 +362,8 @@ static void write_function_stubs(type_t *iface)
             fprintf(client, " _RetVal;\n");\r
         }\r
 \r
             fprintf(client, " _RetVal;\n");\r
         }\r
 \r
-        if (handle_name)\r
+        if (implicit_handle)\r
             print_client("RPC_BINDING_HANDLE _Handle = 0;\n");\r
             print_client("RPC_BINDING_HANDLE _Handle = 0;\n");\r
-\r
         print_client("RPC_MESSAGE _RpcMessage;\n");\r
         print_client("MIDL_STUB_MESSAGE _StubMsg;\n");\r
         fprintf(client, "\n");\r
         print_client("RPC_MESSAGE _RpcMessage;\n");\r
         print_client("MIDL_STUB_MESSAGE _StubMsg;\n");\r
         fprintf(client, "\n");\r
@@ -168,40 +380,41 @@ static void write_function_stubs(type_t *iface)
         indent--;\r
         fprintf(client, "\n");\r
 \r
         indent--;\r
         fprintf(client, "\n");\r
 \r
-        if (handle_name)\r
-            print_client("_Handle = %s;\n", handle_name);\r
+        if (implicit_handle)\r
+        {\r
+            print_client("_Handle = %s;\n", implicit_handle);\r
+            fprintf(client, "\n");\r
+        }\r
+\r
+        /* emit the message buffer size */\r
+        print_client("_StubMsg.BufferLength =");\r
+        print_message_buffer_size(func);\r
+        fprintf(client, ";\n");\r
+\r
 \r
 \r
-        /* FIXME: marshal arguments */\r
-        print_client("_StubMsg.BufferLength = 0UL;\n");\r
-//        print_client("NdrNsGetBuffer(\n");\r
         print_client("NdrGetBuffer(\n");\r
         indent++;\r
         print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
         print_client("_StubMsg.BufferLength,\n");\r
         print_client("NdrGetBuffer(\n");\r
         indent++;\r
         print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
         print_client("_StubMsg.BufferLength,\n");\r
-        if (handle_name)\r
+        if (implicit_handle)\r
             print_client("%_Handle);\n");\r
         else\r
             print_client("%s__MIDL_AutoBindHandle);\n", iface->name);\r
         indent--;\r
         fprintf(client, "\n");\r
 \r
             print_client("%_Handle);\n");\r
         else\r
             print_client("%s__MIDL_AutoBindHandle);\n", iface->name);\r
         indent--;\r
         fprintf(client, "\n");\r
 \r
+        /* marshal arguments */\r
+        marshall_arguments(func);\r
 \r
         /* send/recieve message */\r
 \r
         /* send/recieve message */\r
-//        print_client("NdrNsSendReceive(\n");\r
         print_client("NdrSendReceive(\n");\r
         indent++;\r
         print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
         print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");\r
         print_client("NdrSendReceive(\n");\r
         indent++;\r
         print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
         print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");\r
-//        print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer,\n");\r
-//        print_client("(RPC_BINDING_HANDLE __RPC_FAR *) &%s__MIDL_AutoBindHandle);\n", iface->name);\r
         indent--;\r
 \r
         /* unmarshal return value */\r
         indent--;\r
 \r
         /* unmarshal return value */\r
-        if (is_void(def->type, NULL))\r
-        {\r
-            proc_offset += 2;\r
-        }\r
-        else\r
+        if (!is_void(def->type, NULL))\r
         {\r
             fprintf(client, "\n");\r
 \r
         {\r
             fprintf(client, "\n");\r
 \r
@@ -210,17 +423,27 @@ static void write_function_stubs(type_t *iface)
             print_client("NdrConvert(\n");\r
             indent++;\r
             print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
             print_client("NdrConvert(\n");\r
             indent++;\r
             print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
-            print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString[%u]);\n", proc_offset);\r
+            print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);\r
             indent -= 2;\r
             fprintf(client, "\n");\r
 \r
             print_client("_RetVal = *((");\r
             write_type(client, def->type, def, def->tname);\r
             fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n");\r
             indent -= 2;\r
             fprintf(client, "\n");\r
 \r
             print_client("_RetVal = *((");\r
             write_type(client, def->type, def, def->tname);\r
             fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n");\r
+        }\r
 \r
 \r
-            /* FIXME: update proc_offset */\r
-            proc_offset += 2;\r
+        /* update proc_offset */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                proc_offset += 2; /* FIXME */\r
+                var = PREV_LINK(var);\r
+            }\r
         }\r
         }\r
+        proc_offset += 2;  /* FIXME */\r
 \r
         indent--;\r
         print_client("}\n");\r
 \r
         indent--;\r
         print_client("}\n");\r
@@ -250,7 +473,7 @@ static void write_function_stubs(type_t *iface)
         fprintf(client, "\n");\r
 \r
         method_count++;\r
         fprintf(client, "\n");\r
 \r
         method_count++;\r
-        cur = PREV_LINK(cur);\r
+        func = PREV_LINK(func);\r
     }\r
 }\r
 \r
     }\r
 }\r
 \r
@@ -271,7 +494,7 @@ static void write_stubdescdecl(type_t *iface)
 \r
 static void write_stubdescriptor(type_t *iface)\r
 {\r
 \r
 static void write_stubdescriptor(type_t *iface)\r
 {\r
-    char *handle_name = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
+    char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
 \r
     print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name);\r
     print_client("{\n");\r
 \r
     print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name);\r
     print_client("{\n");\r
@@ -279,8 +502,8 @@ static void write_stubdescriptor(type_t *iface)
     print_client("(void __RPC_FAR *)& %s___RpcClientInterface,\n", iface->name);\r
     print_client("MIDL_user_allocate,\n");\r
     print_client("MIDL_user_free,\n");\r
     print_client("(void __RPC_FAR *)& %s___RpcClientInterface,\n", iface->name);\r
     print_client("MIDL_user_allocate,\n");\r
     print_client("MIDL_user_free,\n");\r
-    if (handle_name)\r
-        print_client("&%s,\n", handle_name);\r
+    if (implicit_handle)\r
+        print_client("&%s,\n", implicit_handle);\r
     else\r
         print_client("&%s__MIDL_AutoBindHandle,\n", iface->name);\r
     print_client("0,\n");\r
     else\r
         print_client("&%s__MIDL_AutoBindHandle,\n", iface->name);\r
     print_client("0,\n");\r
@@ -348,19 +571,34 @@ static void write_formatdesc( const char *str )
 \r
 static void write_formatstringsdecl(type_t *iface)\r
 {\r
 \r
 static void write_formatstringsdecl(type_t *iface)\r
 {\r
-    func_t *cur;\r
     int byte_count = 1;\r
     int byte_count = 1;\r
+    func_t *func;\r
+    var_t *var;\r
 \r
     print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */\r
 \r
     /* determine the proc format string size */\r
 \r
     print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */\r
 \r
     /* determine the proc format string size */\r
-    cur = iface->funcs;\r
-    while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);\r
-    while (cur)\r
+    func = iface->funcs;\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
     {\r
     {\r
+        /* argument list size */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                byte_count += 2; /* FIXME: determine real size */\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
+        /* return value size */\r
         byte_count += 2; /* FIXME: determine real size */\r
         byte_count += 2; /* FIXME: determine real size */\r
-        cur = PREV_LINK(cur);\r
+        func = PREV_LINK(func);\r
     }\r
     }\r
+\r
     print_client("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);\r
 \r
     fprintf(client, "\n");\r
     print_client("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);\r
 \r
     fprintf(client, "\n");\r
@@ -375,11 +613,11 @@ static void write_formatstringsdecl(type_t *iface)
 \r
 static void write_implicithandledecl(type_t *iface)\r
 {\r
 \r
 static void write_implicithandledecl(type_t *iface)\r
 {\r
-    char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
+    char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
 \r
 \r
-    if (var)\r
+    if (implicit_handle)\r
     {\r
     {\r
-        fprintf(client, "handle_t %s;\n", var);\r
+        fprintf(client, "handle_t %s;\n", implicit_handle);\r
         fprintf(client, "\n");\r
     }\r
 }\r
         fprintf(client, "\n");\r
     }\r
 }\r
index 180151e..7a542b4 100644 (file)
@@ -63,7 +63,8 @@ static int print_server(const char *format, ...)
 \r
 static void write_procformatstring(type_t *iface)\r
 {\r
 \r
 static void write_procformatstring(type_t *iface)\r
 {\r
-    func_t *cur = iface->funcs;\r
+    func_t *func = iface->funcs;\r
+    var_t *var;\r
 \r
     print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");\r
     print_server("{\n");\r
 \r
     print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");\r
     print_server("{\n");\r
@@ -72,23 +73,107 @@ static void write_procformatstring(type_t *iface)
     print_server("{\n");\r
     indent++;\r
 \r
     print_server("{\n");\r
     indent++;\r
 \r
-    while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);\r
-    while (cur)\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
     {\r
     {\r
-        var_t *def = cur->def;\r
+        /* emit argument data */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                switch(var->type->type)\r
+                {\r
+                case RPC_FC_BYTE:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_BYTE */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_CHAR:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_CHAR */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_WCHAR:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_WCHAR */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_USHORT:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_USHORT */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_SHORT:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_SHORT */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_ULONG:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_ULONG */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_LONG:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_LONG */\n", var->type->type);\r
+                    break;\r
+                case RPC_FC_HYPER:\r
+                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                    print_server("0x%02x,    /* RPC_FC_HYPER */\n", var->type->type);\r
+                    break;\r
+                default:\r
+                    error("Unknown/unsupported type\n");\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
 \r
 \r
-        if (is_void(def->type, NULL))\r
+        /* emit return value data */\r
+        var = func->def;\r
+        if (is_void(var->type, NULL))\r
         {\r
             print_server("0x5b,    /* FC_END */\n");\r
             print_server("0x5c,    /* FC_PAD */\n");\r
         }\r
         else\r
         {\r
         {\r
             print_server("0x5b,    /* FC_END */\n");\r
             print_server("0x5c,    /* FC_PAD */\n");\r
         }\r
         else\r
         {\r
-            print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-            print_server("0x%02x,    /* <type> */\n", def->type->type);\r
+            switch(var->type->type)\r
+            {\r
+            case RPC_FC_BYTE:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_BYTE */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_CHAR:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_CHAR */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_WCHAR:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_WCHAR */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_USHORT:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_USHORT */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_SHORT:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_SHORT */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_ULONG:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_ULONG */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_LONG:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_LONG */\n", var->type->type);\r
+                break;\r
+            case RPC_FC_HYPER:\r
+                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+                print_server("0x%02x,    /* RPC_FC_HYPER */\n", var->type->type);\r
+                break;\r
+            default:\r
+                error("Unknown/unsupported type\n");\r
+            }\r
         }\r
 \r
         }\r
 \r
-        cur = PREV_LINK(cur);\r
+        func = PREV_LINK(func);\r
     }\r
 \r
     print_server("0x0\n");\r
     }\r
 \r
     print_server("0x0\n");\r
@@ -118,7 +203,7 @@ static void write_typeformatstring(void)
 }\r
 \r
 \r
 }\r
 \r
 \r
-unsigned int get_required_stack_size(type_t *type)\r
+unsigned int get_required_buffer_size(type_t *type)\r
 {\r
     switch(type->type)\r
     {\r
 {\r
     switch(type->type)\r
     {\r
@@ -140,13 +225,81 @@ unsigned int get_required_stack_size(type_t *type)
 }\r
 \r
 \r
 }\r
 \r
 \r
+static void unmarshall_arguments(func_t *func)\r
+{\r
+    unsigned int alignment;\r
+    unsigned int size;\r
+    unsigned int last_size = 0;\r
+    var_t *var;\r
+\r
+    if (!func->args)\r
+        return;\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        alignment = 0;\r
+        switch (var->type->type)\r
+        {\r
+        case RPC_FC_BYTE:\r
+        case RPC_FC_CHAR:\r
+            size = 1;\r
+            alignment = 0;\r
+            break;\r
+\r
+        case RPC_FC_WCHAR:\r
+        case RPC_FC_USHORT:\r
+        case RPC_FC_SHORT:\r
+            size = 2;\r
+            if (last_size != 0 && last_size < 2)\r
+                alignment = (2 - last_size);\r
+            break;\r
+\r
+        case RPC_FC_ULONG:\r
+        case RPC_FC_LONG:\r
+            size = 4;\r
+            if (last_size != 0 && last_size < 4)\r
+                alignment = (4 - last_size);\r
+            break;\r
+\r
+        case RPC_FC_HYPER:\r
+            size = 8;\r
+            if (last_size != 0 && last_size < 4)\r
+                alignment = (4 - last_size);\r
+            break;\r
+\r
+        default:\r
+            error("Unknown/unsupported type!");\r
+        }\r
+\r
+        if (alignment != 0)\r
+            print_server("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+        print_server("");\r
+        write_name(server, var);\r
+        fprintf(server, " = *((");\r
+        write_type(server, var->type, var, var->tname);\r
+        fprintf(server, " __RPC_FAR*)_StubMsg.Buffer)++;\n");\r
+        fprintf(server, "\n");\r
+\r
+        last_size = size;\r
+\r
+        var = PREV_LINK(var);\r
+    }\r
+}\r
+\r
+\r
 static void write_function_stubs(type_t *iface)\r
 {\r
 static void write_function_stubs(type_t *iface)\r
 {\r
-    func_t *cur = iface->funcs;\r
-    while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);\r
-    while (cur)\r
+    func_t *func = iface->funcs;\r
+    var_t *var;\r
+    unsigned int proc_offset = 0;\r
+\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
     {\r
     {\r
-        var_t *def = cur->def;\r
+        var_t *def = func->def;\r
 \r
         write_type(server, def->type, def, def->tname);\r
         fprintf(server, " __RPC_STUB\n");\r
 \r
         write_type(server, def->type, def, def->tname);\r
         fprintf(server, " __RPC_STUB\n");\r
@@ -169,9 +322,28 @@ static void write_function_stubs(type_t *iface)
             fprintf(server, " _RetVal;\n");\r
         }\r
 \r
             fprintf(server, " _RetVal;\n");\r
         }\r
 \r
+        /* declare arguments */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                print_server("");\r
+                write_type(server, var->type, var, var->tname);\r
+                fprintf(server, " ");\r
+                write_name(server, var);\r
+                fprintf(server, ";\n");\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
         print_server("MIDL_STUB_MESSAGE _StubMsg;\n");\r
         print_server("RPC_STATUS _Status;\n");\r
         fprintf(server, "\n");\r
         print_server("MIDL_STUB_MESSAGE _StubMsg;\n");\r
         print_server("RPC_STATUS _Status;\n");\r
         fprintf(server, "\n");\r
+\r
+\r
         print_server("((void)(_Status));\n");\r
         print_server("NdrServerInitializeNew(\n");\r
         indent++;\r
         print_server("((void)(_Status));\n");\r
         print_server("NdrServerInitializeNew(\n");\r
         indent++;\r
@@ -187,6 +359,21 @@ static void write_function_stubs(type_t *iface)
         print_server("RpcTryExcept\n");\r
         print_server("{\n");\r
         indent++;\r
         print_server("RpcTryExcept\n");\r
         print_server("{\n");\r
         indent++;\r
+\r
+        if (func->args)\r
+        {\r
+            print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");\r
+            indent++;\r
+            print_server("NdrConvert(\n");\r
+            indent++;\r
+            print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+            print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);\r
+            indent -= 2;\r
+            fprintf(server, "\n");\r
+\r
+            unmarshall_arguments(func);\r
+        }\r
+\r
         print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");\r
         print_server("{\n");\r
         indent++;\r
         print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");\r
         print_server("{\n");\r
         indent++;\r
@@ -212,14 +399,37 @@ static void write_function_stubs(type_t *iface)
             print_server("");\r
         write_name(server, def);\r
 \r
             print_server("");\r
         write_name(server, def);\r
 \r
-        /* FIXME: handle argument list */\r
-        fprintf(server, "();\n");\r
+        if (func->args)\r
+        {\r
+            int first_arg = 1;\r
 \r
 \r
-        /* FIXME: Marshall the return value */\r
+            fprintf(server, "(\n");\r
+            indent++;\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                if (first_arg)\r
+                    first_arg = 0;\r
+                else\r
+                    fprintf(server, ",\n");\r
+                print_server("");\r
+                write_name(server, var);\r
+                var = PREV_LINK(var);\r
+            }\r
+            fprintf(server, ");\n");\r
+            indent--;\r
+        }\r
+        else\r
+        {\r
+            fprintf(server, "();\n");\r
+        }\r
+\r
+        /* marshall the return value */\r
         if (!is_void(def->type, NULL))\r
         {\r
             fprintf(server, "\n");\r
         if (!is_void(def->type, NULL))\r
         {\r
             fprintf(server, "\n");\r
-            print_server("_StubMsg.BufferLength = %uU;\n", get_required_stack_size(def->type));\r
+            print_server("_StubMsg.BufferLength = %uU;\n", get_required_buffer_size(def->type));\r
             print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");\r
             fprintf(server, "\n");\r
             print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");\r
             print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");\r
             fprintf(server, "\n");\r
             print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");\r
@@ -253,7 +463,20 @@ static void write_function_stubs(type_t *iface)
         fprintf(server, "}\n");\r
         fprintf(server, "\n");\r
 \r
         fprintf(server, "}\n");\r
         fprintf(server, "\n");\r
 \r
-        cur = PREV_LINK(cur);\r
+        /* update proc_offset */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                proc_offset += 2; /* FIXME */\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+        proc_offset += 2;  /* FIXME */\r
+\r
+        func = PREV_LINK(func);\r
     }\r
 }\r
 \r
     }\r
 }\r
 \r
@@ -375,18 +598,32 @@ static void write_formatdesc( const char *str )
 \r
 static void write_formatstringsdecl(type_t *iface)\r
 {\r
 \r
 static void write_formatstringsdecl(type_t *iface)\r
 {\r
-    func_t *cur;\r
+    func_t *func;\r
+    var_t *var;\r
     int byte_count = 1;\r
 \r
     print_server("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */\r
 \r
     /* determine the proc format string size */\r
     int byte_count = 1;\r
 \r
     print_server("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */\r
 \r
     /* determine the proc format string size */\r
-    cur = iface->funcs;\r
-    while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);\r
-    while (cur)\r
+    func = iface->funcs;\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
     {\r
     {\r
+        /* argument list size */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                byte_count += 2; /* FIXME: determine real size */\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
+        /* return value size */\r
         byte_count += 2; /* FIXME: determine real size */\r
         byte_count += 2; /* FIXME: determine real size */\r
-        cur = PREV_LINK(cur);\r
+        func = PREV_LINK(func);\r
     }\r
     print_server("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);\r
 \r
     }\r
     print_server("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);\r
 \r