From d1aa5ddca997bc92aae53b9d009debdd38c833f2 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Sat, 9 Jan 2016 16:22:15 +0800
Subject: widl: Calculate size of instance for structures.

---
 tools/widl/write_sltg.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c
index 20dd05d..05cda99 100644
--- a/tools/widl/write_sltg.c
+++ b/tools/widl/write_sltg.c
@@ -546,7 +546,7 @@ static int get_element_size(type_t *type)
     return 0;
 }
 
-static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset)
+static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset, int *size_instance)
 {
     short vt, desc_offset;
 
@@ -555,7 +555,7 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s
 
     if (is_array(type) && !type_array_is_decl_as_ptr(type))
     {
-        int num_dims, elements, array_start, size;
+        int num_dims, elements, array_start, size, array_size;
         type_t *atype;
         struct
         {
@@ -591,22 +591,28 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s
 
         array->cDims = num_dims;
         array->fFeatures = 0x0004; /* FADF_EMBEDDED */
-        array->cbElements = get_element_size(type_array_get_element(type));
+        array->cbElements = get_element_size(atype);
         array->cLocks = 0;
         array->pvData = NULL;
 
         bound = array->bound;
+
+        array_size = array->cbElements;
         atype = type;
 
         while (is_array(atype) && !type_array_is_decl_as_ptr(atype))
         {
             bound[0] = type_array_get_dim(atype);
+            array_size *= bound[0];
             bound[1] = 0;
             bound += 2;
 
             atype = type_array_get_element(atype);
         }
 
+        *size_instance += array_size;
+        size_instance = NULL; /* don't account for element size */
+
         append_data(data, array, size);
 
         desc_offset = data->size;
@@ -632,15 +638,18 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s
             chat("write_var_desc: vt VT_PTR | 0x0400\n");
             vt = VT_PTR | 0x0400;
             append_data(data, &vt, sizeof(vt));
-            write_var_desc(data, ref, 0, base_offset);
+            write_var_desc(data, ref, 0, base_offset, size_instance);
         }
         else
-            write_var_desc(data, ref, 0x0e00, base_offset);
+            write_var_desc(data, ref, 0x0e00, base_offset, size_instance);
         return desc_offset;
     }
 
     chat("write_var_desc: vt %d, flags %04x\n", vt, flags);
 
+    if (size_instance)
+        *size_instance += get_element_size(type);
+
     vt |= flags;
     append_data(data, &vt, sizeof(vt));
 
@@ -654,7 +663,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t
     struct sltg_typeinfo_header ti;
     struct sltg_member_header member;
     struct sltg_tail tail;
-    int member_offset, var_count = 0, var_data_size = 0;
+    int member_offset, var_count = 0, var_data_size = 0, size_instance = 0;
     short *type_desc_offset = NULL;
 
     chat("add_structure_typeinfo: %s\n", type->name);
@@ -686,7 +695,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t
             init_sltg_data(&var_data[i]);
 
             base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable);
-            type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset);
+            type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset, &size_instance);
             dump_var_desc(var_data[i].data, var_data[i].size);
 
             if (var_data[i].size > sizeof(short))
@@ -762,7 +771,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t
     tail.res1a = 0;
     tail.simple_alias = 0;
     tail.res1e = 0;
-    tail.cbSizeInstance = 0;
+    tail.cbSizeInstance = size_instance;
     tail.cbAlignment = 4;
     tail.res24 = -1;
     tail.res26 = -1;
-- 
2.6.4

