- Support conformant arrays as in and out parameters.
authorEric Kohl <eric.kohl@reactos.org>
Sat, 30 Jul 2005 19:31:52 +0000 (19:31 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 30 Jul 2005 19:31:52 +0000 (19:31 +0000)
- Fix message buffer size calculation for client and server.

svn path=/trunk/; revision=16903

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

index 887ebd3..b0953cc 100644 (file)
@@ -1,5 +1,13 @@
 ChangeLog
 
+2005-07-30 ekohl
+
+   tools/widl/client.c
+   tools/widl/server.c
+
+- Support conformant arrays as in and out parameters.
+- Fix message buffer size calculation for client and server.
+
 2005-07-25 ekohl
 
    tools/widl/client.c
index dc0bf8a..0eba384 100644 (file)
@@ -518,7 +518,7 @@ static void write_typeformatstring(type_t *iface)
                     if (ptr_attr + ref_attr + unique_attr == 0)\r
                         ref_attr = 1;\r
 \r
-                    if (sizeis_attr && out_attr)\r
+                    if (sizeis_attr)\r
                     {\r
                         unsigned char type_type = 0;\r
 \r
@@ -553,12 +553,17 @@ static void write_typeformatstring(type_t *iface)
                             print_client("0x%02x,\n", get_type_alignment(var->type) - 1);\r
                             print_client("NdrFcShort(0x%02x),\n", get_type_size(var->type, 1));\r
                             print_client("0x%02x,\n", 0x20 + type_type);\r
-                            print_client("0x00,\n");\r
+                            if (out_attr)\r
+                                print_client("0x54,          /* FC_DEREFERENCE */\n");\r
+                            else\r
+                                print_client("0x00,          /*  */\n");\r
 \r
                             fprintf(client, "#ifndef _ALPHA_\n");\r
-                            print_client("NdrFcShort(0x04),\n");\r
+                            print_client("NdrFcShort(0x%02X),\n",\r
+                                         get_var_stack_offset_32(func, ((var_t *)sizeis_attr)->name));\r
                             fprintf(client, "#else\n");\r
-                            print_client("NdrFcShort(0x08),\n");\r
+                            print_client("NdrFcShort(0x%02X),\n",\r
+                                         get_var_stack_offset_64(func, ((var_t *)sizeis_attr)->name));\r
                             fprintf(client, "#endif\n");\r
                             print_client("0x%02x,\n", get_base_type(var->type->type));\r
                             print_client("0x5b,          /* FC_END */\n");\r
@@ -566,16 +571,23 @@ static void write_typeformatstring(type_t *iface)
                     }\r
                     else if (is_base_type(var->type))\r
                     {\r
-                        if (out_attr)\r
-                            print_client("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");\r
+                        if (out_attr && !in_attr)\r
+                        {\r
+                            if (ref_attr)\r
+                                print_client("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");\r
+                            else if (unique_attr)\r
+                                print_client("0x12, 0x0c,    /* FC_FP [allocated_on_stack] [simple_pointer] */\n");\r
+                            else if (ptr_attr)\r
+                                print_client("0x14, 0x0c,    /* FC_FP [allocated_on_stack] [simple_pointer] */\n");\r
+                        }\r
                         else\r
                         {\r
-                            if (ptr_attr)\r
-                                print_client("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");\r
-                            else if (ref_attr)\r
+                            if (ref_attr)\r
                                 print_client("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");\r
                             else if (unique_attr)\r
                                 print_client("0x12, 0x08,    /* FC_UP [simple_pointer] */\n");\r
+                            else if (ptr_attr)\r
+                                print_client("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");\r
                         }\r
 \r
                         if (string_attr)\r
@@ -614,6 +626,7 @@ static void write_typeformatstring(type_t *iface)
 \r
 static void print_message_buffer_size(func_t *func, unsigned int *type_offset)\r
 {\r
+    unsigned int local_type_offset = *type_offset;\r
     unsigned int alignment;\r
     int size;\r
     int last_size = -1;\r
@@ -622,8 +635,9 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
     int string_attr;\r
     int nothing_printed = 1;\r
     int ptr_attr, ref_attr, unique_attr;\r
+    int padding = 0, first_padding = 0;\r
+    void *sizeis_attr;\r
     var_t *var;\r
-    unsigned int local_type_offset = *type_offset;\r
 \r
     print_client("_StubMsg.BufferLength =");\r
     if (func->args)\r
@@ -634,7 +648,6 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
         {\r
             out_attr = is_attr(var->attrs, ATTR_OUT);\r
             in_attr = is_attr(var->attrs, ATTR_IN);\r
-            string_attr = is_attr(var->attrs, ATTR_STRING);\r
 \r
             /* set 'in' attribute if neither 'in' nor 'out' is found */\r
             if (!out_attr && !in_attr)\r
@@ -651,43 +664,32 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
             if (!in_attr)\r
                 continue;\r
 \r
+            string_attr = is_attr(var->attrs, ATTR_STRING);\r
+            sizeis_attr = get_attrp(var->attrs, ATTR_SIZEIS);\r
+\r
             if (var->ptr_level == 1)\r
             {\r
-                if (unique_attr)\r
+                if (string_attr && !sizeis_attr)\r
                 {\r
-                    if (string_attr &&\r
-                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                    /* non-sized conformant string */\r
+                    if (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR)\r
                     {\r
-                        size = 16;\r
+                        size = (unique_attr) ? 16 : 12;\r
                         alignment = 0;\r
-                        if (last_size != -1)\r
-                            fprintf(client, " +");\r
-                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
-                        nothing_printed = 0;\r
-                    }\r
-                    else\r
-                    {\r
-                        size = 8;\r
-                        alignment = 0;\r
-                        if (last_size != -1)\r
-                            fprintf(client, " +");\r
-                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
-                        nothing_printed = 0;\r
                     }\r
                 }\r
-                else if (ref_attr)\r
+                else if (sizeis_attr && !string_attr)\r
                 {\r
-                    if (string_attr &&\r
-                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
-                    {\r
-                        size = 12;\r
-                        alignment = 0;\r
-                        if (last_size != -1)\r
-                            fprintf(client, " +");\r
-                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
-                        nothing_printed = 0;\r
-                    }\r
-                    else\r
+                    /* conformant arrays */\r
+                    size = 4;\r
+                    alignment = 0;\r
+                    if (padding != 0)\r
+                        padding = 1;\r
+                }\r
+                else if (!sizeis_attr && !string_attr)\r
+                {\r
+                    /* simple pointers */\r
+                    if (is_base_type(var->type))\r
                     {\r
                         alignment = 0;\r
                         switch (var->type->type)\r
@@ -726,27 +728,17 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
                             size = 0;\r
                             break;\r
 \r
-                        case 0:\r
-                            printf("%s\n", __FUNCTION__);\r
-                            printf("ptr_level %d\n", var->ptr_level);\r
-                            printf("Type %p\n", var->type);\r
-                            printf("Type %x\n", var->type->type);\r
-                            printf("Type name: %s\n", var->type->name);\r
-                            printf("Tref %p\n", var->type->ref);\r
-                            printf("Tref->name %s\n", var->type->ref->name);\r
-                            printf("Tref->ref %p\n", var->type->ref->ref);\r
-                            return;\r
-\r
                         default:\r
                             error("%s:%d Unknown/unsupported type 0x%x\n",\r
                                   __FUNCTION__,__LINE__, var->type->type);\r
                             return;\r
                         }\r
-\r
-                        if (last_size != -1)\r
-                            fprintf(client, " +");\r
-                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
-                        nothing_printed = 0;\r
+                    }\r
+                    else\r
+                    {\r
+                        /* simple pointer to a struct */\r
+                        size = 8;\r
+                        alignment = 0;\r
                     }\r
                 }\r
             }\r
@@ -800,11 +792,33 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
                           __FUNCTION__,__LINE__, var->type->type);\r
                     return;\r
                 }\r
+            }\r
 \r
-                if (last_size != -1)\r
-                    fprintf(client, " +");\r
-                fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
-                nothing_printed = 0;\r
+            if (last_size != -1)\r
+                fprintf(client, " +");\r
+            fprintf(client, " %dU", (size == 0) ? 0 : size + alignment + first_padding + padding);\r
+            nothing_printed = 0;\r
+            if (first_padding != 0)\r
+                first_padding = 0;\r
+\r
+            /* set paddings */\r
+            if (var->ptr_level == 1)\r
+            {\r
+                if (string_attr && !sizeis_attr)\r
+                {\r
+                    /* non-sized conformant string */\r
+                    if (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR)\r
+                    {\r
+                        first_padding = 3;\r
+                        padding = 3;\r
+                    }\r
+                }\r
+                else if (sizeis_attr && !string_attr)\r
+                {\r
+                    /* conformant arrays */\r
+                    first_padding = 4;\r
+                    padding = 3;\r
+                }\r
             }\r
 \r
             last_size = size;\r
@@ -827,9 +841,8 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
         {\r
             out_attr = is_attr(var->attrs, ATTR_OUT);\r
             in_attr = is_attr(var->attrs, ATTR_IN);\r
-            string_attr = is_attr(var->attrs, ATTR_STRING);\r
 \r
-            /* set 'in' attribute if neither 'in' nor 'out' is found */\r
+            /* default to 'in' attribute */\r
             if (!out_attr && !in_attr)\r
                 in_attr = 1;\r
 \r
@@ -841,12 +854,15 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
             if (ptr_attr + ref_attr + unique_attr == 0)\r
                 ref_attr = 1;\r
 \r
+            string_attr = is_attr(var->attrs, ATTR_STRING);\r
+            sizeis_attr = get_attrp(var->attrs, ATTR_SIZEIS);\r
+\r
             if (in_attr)\r
             {\r
-                if (var->ptr_level == 0 &&\r
-                    var->type->type == RPC_FC_RP)\r
+                if (var->ptr_level == 0)\r
                 {\r
-                    if (var->type->ref->ref->type == RPC_FC_STRUCT)\r
+                    if (var->type->type == RPC_FC_RP &&\r
+                        var->type->ref->ref->type == RPC_FC_STRUCT)\r
                     {\r
                         print_client("NdrSimpleStructBufferSize(\n");\r
                         indent++;\r
@@ -858,35 +874,59 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
                         indent--;\r
                     }\r
                 }\r
-                else if (var->ptr_level == 1 &&\r
-                         string_attr &&\r
-                         (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                else if (var->ptr_level == 1)\r
                 {\r
-                    if (ptr_attr)\r
-                    {\r
-                        /* FIXME: not supported yet */\r
-                    }\r
-                    if (ref_attr)\r
+                    if (string_attr)\r
                     {\r
-                        print_client("NdrConformantStringBufferSize(\n");\r
-                        indent++;\r
-                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
-                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
-                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
-                                     local_type_offset + 2);\r
-                        nothing_printed = 1;\r
-                        indent--;\r
+                        if ((var->type->type == RPC_FC_CHAR ||\r
+                             var->type->type == RPC_FC_WCHAR))\r
+                        {\r
+                            if (ptr_attr)\r
+                            {\r
+                                /* FIXME: not supported yet */\r
+                            }\r
+                            if (ref_attr)\r
+                            {\r
+                                print_client("NdrConformantStringBufferSize(\n");\r
+                                indent++;\r
+                                print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                                print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                                print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                             local_type_offset + 2);\r
+                                nothing_printed = 1;\r
+                                indent--;\r
+                            }\r
+                            else if (unique_attr)\r
+                            {\r
+                                print_client("NdrPointerBufferSize(\n");\r
+                                indent++;\r
+                                print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                                print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                                print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                             local_type_offset);\r
+                                nothing_printed = 1;\r
+                                indent--;\r
+                            }\r
+                        }\r
                     }\r
-                    else if (unique_attr)\r
+                    else\r
                     {\r
-                        print_client("NdrPointerBufferSize(\n");\r
-                        indent++;\r
-                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
-                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
-                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
-                                     local_type_offset);\r
-                        nothing_printed = 1;\r
-                        indent--;\r
+                        if (sizeis_attr)\r
+                        {\r
+                            fprintf(client, "\n");\r
+                            print_client("_StubMsg.MaxCount = %s;\n",\r
+                                         ((var_t *)sizeis_attr)->name);\r
+                            fprintf(client, "\n");\r
+\r
+                            print_client("NdrConformantArrayBufferSize(\n");\r
+                            indent++;\r
+                            print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                            print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                            print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                         local_type_offset + 4);\r
+                            indent--;\r
+                            nothing_printed = 1;\r
+                        }\r
                     }\r
                 }\r
             }\r
@@ -903,6 +943,7 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
 \r
 static void marshall_in_arguments(func_t *func, unsigned int *type_offset)\r
 {\r
+    unsigned int local_type_offset = *type_offset;\r
     unsigned int alignment;\r
     unsigned int size;\r
     unsigned int last_size = 0;\r
@@ -910,8 +951,8 @@ static void marshall_in_arguments(func_t *func, unsigned int *type_offset)
     int out_attr;\r
     int string_attr;\r
     int ptr_attr, ref_attr, unique_attr;\r
+    void *sizeis_attr;\r
     var_t *var;\r
-    unsigned int local_type_offset = *type_offset;\r
 \r
     if (!func->args)\r
         return;\r
@@ -922,7 +963,6 @@ static void marshall_in_arguments(func_t *func, unsigned int *type_offset)
     {\r
         out_attr = is_attr(var->attrs, ATTR_OUT);\r
         in_attr = is_attr(var->attrs, ATTR_IN);\r
-        string_attr = is_attr(var->attrs, ATTR_STRING);\r
 \r
         /* set 'in' attribute if neither 'in' nor 'out' is set */\r
         if (!out_attr && !in_attr)\r
@@ -945,7 +985,27 @@ static void marshall_in_arguments(func_t *func, unsigned int *type_offset)
                 if (ptr_attr + ref_attr + unique_attr == 0)\r
                     ref_attr = 1;\r
 \r
-                if (ref_attr)\r
+                string_attr = is_attr(var->attrs, ATTR_STRING);\r
+                sizeis_attr = get_attrp(var->attrs, ATTR_SIZEIS);\r
+\r
+                if (sizeis_attr)\r
+                {\r
+                    print_client("_StubMsg.MaxCount = %s;\n",\r
+                                 ((var_t *)sizeis_attr)->name);\r
+                    fprintf(client, "\n");\r
+\r
+                    print_client("NdrConformantArrayMarshall(\n");\r
+                    indent++;\r
+                    print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                    print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                    print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                 local_type_offset + 4);\r
+                    indent--;\r
+                    fprintf(client, "\n");\r
+                    print_client("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
+                    fprintf(client, "\n");\r
+                }\r
+                else if (ref_attr)\r
                 {\r
                     if (string_attr &&\r
                         (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
@@ -1192,6 +1252,8 @@ static void unmarshall_out_arguments(func_t *func, unsigned int *type_offset)
                         print_client("(unsigned char)0);\n");\r
                         indent--;\r
                         fprintf(client, "\n");\r
+                        print_client("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
+                        fprintf(client, "\n");\r
                     }\r
                 }\r
                 else if (is_base_type(var->type))\r
index 6d4ccb5..e586349 100644 (file)
@@ -515,7 +515,7 @@ static void write_typeformatstring(type_t *iface)
                     if (ptr_attr + ref_attr + unique_attr == 0)\r
                         ref_attr = 1;\r
 \r
-                    if (sizeis_attr != NULL && out_attr)\r
+                    if (sizeis_attr)\r
                     {\r
                         unsigned char type_type = 0;\r
 \r
@@ -550,12 +550,17 @@ static void write_typeformatstring(type_t *iface)
                             print_server("0x%02x,\n", get_type_alignment(var->type) - 1);\r
                             print_server("NdrFcShort(0x%02x),\n", get_type_size(var->type, 1));\r
                             print_server("0x%02x,\n", 0x20 + type_type);\r
-                            print_server("0x00,\n");\r
+                            if (out_attr)\r
+                                print_server("0x54           /* FC_DEREFERENCE */,\n");\r
+                            else\r
+                                print_server("0x00           /*  */,\n");\r
 \r
                             fprintf(server, "#ifndef _ALPHA_\n");\r
-                            print_server("NdrFcShort(0x04),\n");\r
+                            print_server("NdrFcShort(0x%02X),\n",\r
+                                         get_var_stack_offset_32(func, ((var_t *)sizeis_attr)->name));\r
                             fprintf(server, "#else\n");\r
-                            print_server("NdrFcShort(0x08),\n");\r
+                            print_server("NdrFcShort(0x%02X),\n",\r
+                                         get_var_stack_offset_64(func, ((var_t *)sizeis_attr)->name));\r
                             fprintf(server, "#endif\n");\r
                             print_server("0x%02x,\n", get_base_type(var->type->type));\r
                             print_server("0x5b,          /* FC_END */\n");\r
@@ -563,16 +568,23 @@ static void write_typeformatstring(type_t *iface)
                     }\r
                     else if (is_base_type(var->type))\r
                     {\r
-                        if (out_attr)\r
-                            print_server("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");\r
+                        if (out_attr && !in_attr)\r
+                        {\r
+                            if (ref_attr)\r
+                                print_server("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");\r
+                            else if (unique_attr)\r
+                                print_server("0x12, 0x0c,    /* FC_FP [allocated_on_stack] [simple_pointer] */\n");\r
+                            else if (ptr_attr)\r
+                                print_server("0x14, 0x0c,    /* FC_FP [allocated_on_stack] [simple_pointer] */\n");\r
+                        }\r
                         else\r
                         {\r
-                            if (ptr_attr)\r
-                                print_server("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");\r
-                            else if (ref_attr)\r
+                            if (ref_attr)\r
                                 print_server("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");\r
                             else if (unique_attr)\r
                                 print_server("0x12, 0x08,    /* FC_UP [simple_pointer] */\n");\r
+                            else if (ptr_attr)\r
+                                print_server("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");\r
                         }\r
 \r
                         if (string_attr)\r
@@ -623,8 +635,8 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
     int empty_line;\r
     var_t *var;\r
 \r
-    int add_return = 0;\r
-    int start_new_line = 0;\r
+    int first_padding = 0;\r
+    int padding = 0;\r
     int add_plus = 0;\r
 \r
     unsigned int local_type_offset = *type_offset;\r
@@ -643,97 +655,104 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
 \r
             if (out_attr)\r
             {\r
-                if (var->ptr_level == 1 &&\r
-                    string_attr &&\r
-                    sizeis_attr != NULL &&\r
-                    (var->type->type == RPC_FC_BYTE ||\r
-                     var->type->type == RPC_FC_CHAR ||\r
-                     var->type->type == RPC_FC_WCHAR))\r
+                if (var->ptr_level == 1)\r
                 {\r
-                   fprintf(server, " 12U");\r
-                   add_return = 6;\r
-                   if (var->type->type == RPC_FC_BYTE ||\r
-                       var->type->type == RPC_FC_CHAR)\r
-                       add_return++;\r
-                   add_plus = 1;\r
-                }\r
-                else if (is_base_type(var->type))\r
-                {\r
-                    if (start_new_line)\r
+                    if (sizeis_attr)\r
                     {\r
-                        print_server("_StubMsg.BufferLength +=");\r
+                        if (string_attr &&\r
+                            (var->type->type == RPC_FC_BYTE ||\r
+                             var->type->type == RPC_FC_CHAR ||\r
+                             var->type->type == RPC_FC_WCHAR))\r
+                        {\r
+                            size =12;\r
+                        }\r
+                        else\r
+                        {\r
+                            size = 4;\r
+                        }\r
                     }\r
-\r
-                    alignment = 0;\r
-                    switch (var->type->type)\r
+                    else if (is_base_type(var->type))\r
                     {\r
-                    case RPC_FC_BYTE:\r
-                    case RPC_FC_CHAR:\r
-                    case RPC_FC_SMALL:\r
-                        size = 1;\r
                         alignment = 0;\r
-                        break;\r
+                        switch (var->type->type)\r
+                        {\r
+                        case RPC_FC_BYTE:\r
+                        case RPC_FC_CHAR:\r
+                        case RPC_FC_SMALL:\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
+                        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
-                    case RPC_FC_FLOAT:\r
-                        size = 4;\r
-                        if (last_size > 0 && last_size < 4)\r
-                            alignment += (4 - last_size);\r
-                        break;\r
+                        case RPC_FC_ULONG:\r
+                        case RPC_FC_LONG:\r
+                        case RPC_FC_FLOAT:\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
-                    case RPC_FC_DOUBLE:\r
-                        size = 8;\r
-                        if (last_size > 0 && last_size < 4)\r
-                            alignment += (4 - last_size);\r
-                        break;\r
+                        case RPC_FC_HYPER:\r
+                        case RPC_FC_DOUBLE:\r
+                            size = 8;\r
+                            if (last_size > 0 && last_size < 4)\r
+                                alignment += (4 - last_size);\r
+                            break;\r
 \r
-                    default:\r
-                        error("%s:%d Unknown/unsupported type 0x%x\n",\r
-                              __FUNCTION__,__LINE__, var->type->type);\r
-                        return;\r
+                        default:\r
+                            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                                  __FUNCTION__,__LINE__, var->type->type);\r
+                            return;\r
+                        }\r
                     }\r
+                }\r
+                else if (var->type->type == RPC_FC_RP)\r
+                {\r
+                    size = 12;\r
+                }\r
 \r
+                if (size != 0)\r
+                {\r
                     if (add_plus)\r
                         fprintf(server, " +");\r
-                    fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);\r
+                    fprintf(server, " %dU", size + alignment + first_padding + padding);\r
+\r
+                    if (first_padding != 0)\r
+                        first_padding = 0;\r
 \r
                     last_size = size;\r
-                    start_new_line = 0;\r
                     add_plus = 1;\r
                 }\r
-                else if (var->type->type == RPC_FC_RP)\r
+\r
+                /* set paddings */\r
+                if (var->ptr_level == 1)\r
                 {\r
-                    if (size == 0)\r
+                    if (sizeis_attr)\r
                     {\r
-                      fprintf(server, " 12U;\n");\r
-                    }\r
-                    else if (last_size != 0)\r
-                    {\r
-                      fprintf(server, " + 12U;\n");\r
-                      last_size = 0;\r
+                        if (string_attr &&\r
+                            (var->type->type == RPC_FC_BYTE ||\r
+                             var->type->type == RPC_FC_CHAR ||\r
+                             var->type->type == RPC_FC_WCHAR))\r
+                        {\r
+                            first_padding = 3;\r
+                            if (var->type->type == RPC_FC_BYTE ||\r
+                                var->type->type == RPC_FC_CHAR)\r
+                                first_padding++;\r
+                            padding = 3;\r
+                        }\r
+                        else\r
+                        {\r
+                            first_padding = 4;\r
+                            padding = 3;\r
+                        }\r
                     }\r
-\r
-                    fprintf(server,"\n");\r
-                    print_server("NdrSimpleStructBufferSize(\n");\r
-                    indent++;\r
-                    print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
-                    print_server("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
-                    print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
-                                 local_type_offset + 4); /* FIXME */\r
-                    indent--;\r
-                    fprintf(server,"\n");\r
-\r
-                    start_new_line = 1;\r
                 }\r
 \r
                 /* calculate the next type offset */\r
@@ -745,12 +764,6 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
     /* return value size */\r
     if (!is_void(func->def->type, NULL))\r
     {\r
-        if (start_new_line)\r
-        {\r
-          print_server("_StubMsg.BufferLength +=");\r
-          add_plus = 0;\r
-        }\r
-\r
         switch(func->def->type->type)\r
         {\r
         case RPC_FC_BYTE:\r
@@ -783,8 +796,12 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
         if (add_plus)\r
             fprintf(server, " +");\r
 \r
-        fprintf(server, " %dU", (size == 0) ? 0 : size + alignment + add_return);\r
+        fprintf(server, " %dU", size + alignment + first_padding + padding);\r
     }\r
+\r
+    if (size == 0)\r
+        fprintf(server, "0U");\r
+\r
     fprintf(server, ";\n");\r
 \r
 \r
@@ -808,24 +825,55 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
 \r
             if (out_attr)\r
             {\r
-                if (var->ptr_level == 1 &&\r
-                    string_attr &&\r
-                    sizeis_attr != NULL &&\r
-                    (var->type->type == RPC_FC_BYTE ||\r
-                     var->type->type == RPC_FC_CHAR ||\r
-                     var->type->type == RPC_FC_WCHAR))\r
+                if (var->ptr_level == 1 && sizeis_attr != NULL)\r
                 {\r
-                    print_server("_StubMsg.MaxCount = %s;\n", ((var_t *)sizeis_attr)->name);\r
-                    fprintf(server, "\n");\r
-                    print_server("NdrConformantStringBufferSize(\n");\r
+                    if (string_attr)\r
+                    {\r
+                        if (var->type->type == RPC_FC_BYTE ||\r
+                            var->type->type == RPC_FC_CHAR ||\r
+                            var->type->type == RPC_FC_WCHAR)\r
+                        {\r
+                            print_server("_StubMsg.MaxCount = %s;\n", ((var_t *)sizeis_attr)->name);\r
+                            fprintf(server, "\n");\r
+                            print_server("NdrConformantStringBufferSize(\n");\r
+                            indent++;\r
+                            print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                            print_server("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                            print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                         local_type_offset + 4);\r
+                            indent--;\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        if (((var_t *)sizeis_attr)->ptr_level == 0)\r
+                            print_server("_StubMsg.MaxCount = %s;\n", ((var_t *)sizeis_attr)->name);\r
+                        else\r
+                            print_server("_StubMsg.MaxCount = %s ? *%s : 0;\n",\r
+                                         ((var_t *)sizeis_attr)->name, ((var_t *)sizeis_attr)->name);\r
+                        fprintf(server, "\n");\r
+                        print_server("NdrConformantArrayBufferSize(\n");\r
+                        indent++;\r
+                        print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                        print_server("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                        print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                     local_type_offset + 4);\r
+                        indent--;\r
+                    }\r
+\r
+                    empty_line = 1;\r
+                }\r
+                else if (var->type->type == RPC_FC_RP)\r
+                {\r
+                    fprintf(server,"\n");\r
+                    print_server("NdrSimpleStructBufferSize(\n");\r
                     indent++;\r
                     print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
                     print_server("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
                     print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
-                                 local_type_offset + 4);\r
+                                 local_type_offset + 4); /* FIXME */\r
                     indent--;\r
-\r
-                    empty_line = 1;\r
+                    fprintf(server,"\n");\r
                 }\r
             }\r
 \r
@@ -873,6 +921,7 @@ static void print_message_buffer_size(func_t *func, unsigned int *type_offset)
 static void init_pointers (func_t *func)\r
 {\r
     var_t *var;\r
+    int count = 0;\r
 \r
     if (!func->args)\r
         return;\r
@@ -888,13 +937,15 @@ static void init_pointers (func_t *func)
                 print_server("*(");\r
                 write_type(server, var->type, NULL, var->tname);\r
                 fprintf(server, "*)&%s = NULL;\n", var->name);\r
+                count++;\r
             }\r
         }\r
         else if (var->ptr_level == 1)\r
         {\r
-            fprintf(server, "%s = (", var->name);\r
+            print_server("%s = (", var->name);\r
             write_type(server, var->type, NULL, var->tname);\r
-            print_server(" __RPC_FAR *)0;\n");\r
+            fprintf(server, " __RPC_FAR *)0;\n");\r
+            count++;\r
         }\r
         else if (var->ptr_level > 1)\r
         {\r
@@ -904,12 +955,15 @@ static void init_pointers (func_t *func)
 \r
         var = PREV_LINK(var);\r
     }\r
-    fprintf(server, "\n");\r
+\r
+    if (count > 0)\r
+        fprintf(server, "\n");\r
 }\r
 \r
 \r
 static void unmarshall_in_arguments(func_t *func, unsigned int *type_offset)\r
 {\r
+    unsigned int local_type_offset = *type_offset;\r
     unsigned int alignment;\r
     unsigned int size;\r
     unsigned int last_size = 0;\r
@@ -917,7 +971,7 @@ static void unmarshall_in_arguments(func_t *func, unsigned int *type_offset)
     int in_attr, out_attr;\r
     int string_attr;\r
     int ptr_attr, ref_attr, unique_attr;\r
-    unsigned int local_type_offset = *type_offset;\r
+    void *sizeis_attr;\r
 \r
     if (!func->args)\r
         return;\r
@@ -928,12 +982,14 @@ static void unmarshall_in_arguments(func_t *func, unsigned int *type_offset)
     {\r
         out_attr = is_attr(var->attrs, ATTR_OUT);\r
         in_attr = is_attr(var->attrs, ATTR_IN);\r
-        string_attr = is_attr(var->attrs, ATTR_STRING);\r
 \r
         /* set 'in' attribute if neither 'in' nor 'out' is set */\r
         if (!out_attr && !in_attr)\r
             in_attr = 1;\r
 \r
+        string_attr = is_attr(var->attrs, ATTR_STRING);\r
+        sizeis_attr = get_attrp(var->attrs, ATTR_SIZEIS);\r
+\r
         if (in_attr)\r
         {\r
             if (var->ptr_level == 1)\r
@@ -946,20 +1002,36 @@ static void unmarshall_in_arguments(func_t *func, unsigned int *type_offset)
 \r
                 if (ref_attr)\r
                 {\r
-                    if (string_attr &&\r
-                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                    if (string_attr)\r
                     {\r
-                        print_server("NdrConformantStringUnmarshall(\n");\r
-                        indent++;\r
-                        print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
-                        print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);\r
-                        print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",\r
-                                     local_type_offset + 2);\r
-                        print_server("(unsigned char)0);\n");\r
-                        indent--;\r
-                        fprintf(server, "\n");\r
-                        print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
-                        fprintf(server, "\n");\r
+                        if (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR)\r
+                        {\r
+                            print_server("NdrConformantStringUnmarshall(\n");\r
+                            indent++;\r
+                            print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                            print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);\r
+                            print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",\r
+                                         local_type_offset + 2);\r
+                            print_server("(unsigned char)0);\n");\r
+                            indent--;\r
+                            fprintf(server, "\n");\r
+                            print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
+                            fprintf(server, "\n");\r
+                        }\r
+                    }\r
+                    else if (sizeis_attr)\r
+                    {\r
+                            print_server("NdrConformantArrayUnmarshall(\n");\r
+                            indent++;\r
+                            print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                            print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);\r
+                            print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",\r
+                                         local_type_offset + 4);\r
+                            print_server("(unsigned char)0);\n");\r
+                            indent--;\r
+                            fprintf(server, "\n");\r
+                            print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
+                            fprintf(server, "\n");\r
                     }\r
                     else\r
                     {\r
@@ -1173,6 +1245,26 @@ static void marshall_out_arguments(func_t *func, unsigned int *type_offset)
                         print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
                         fprintf(server, "\n");\r
                     }\r
+                    else\r
+                    {\r
+                        fprintf(server, "\n");\r
+                        if (((var_t *)sizeis_attr)->ptr_level == 0)\r
+                            print_server("_StubMsg.MaxCount = %s;\n", ((var_t *)sizeis_attr)->name);\r
+                        else\r
+                            print_server("_StubMsg.MaxCount = %s ? *%s : 0;\n",\r
+                                         ((var_t *)sizeis_attr)->name, ((var_t *)sizeis_attr)->name);\r
+                        fprintf(server, "\n");\r
+                        print_server("NdrConformantArrayMarshall(\n");\r
+                        indent++;\r
+                        print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                        print_server("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                        print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                     local_type_offset + 4);\r
+                        indent--;\r
+                        fprintf(server, "\n");\r
+                        print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");\r
+                        fprintf(server, "\n");\r
+                    }\r
                 }\r
                 else if (is_base_type(var->type))\r
                 {\r
@@ -1575,8 +1667,12 @@ static void write_function_stubs(type_t *iface)
                     {\r
                         print_server("");\r
                         write_name(server, var);\r
-                        fprintf(server, " = NdrAllocate(&_StubMsg, %s * %d);\n",\r
-                                ((var_t *)sizeis_attr)->name, get_type_size(var->type, 1));\r
+                        if (((var_t *)sizeis_attr)->ptr_level == 0)\r
+                            fprintf(server, " = NdrAllocate(&_StubMsg, %s * %d);\n",\r
+                                    ((var_t *)sizeis_attr)->name, get_type_size(var->type, 1));\r
+                        else if (((var_t *)sizeis_attr)->ptr_level == 1)\r
+                            fprintf(server, " = NdrAllocate(&_StubMsg, *%s * %d);\n",\r
+                                    ((var_t *)sizeis_attr)->name, get_type_size(var->type, 1));\r
                         sep = 1;\r
                     }\r
                     else\r