Support 'ref' and 'unique' attributes for pointers.
Modified: trunk/reactos/tools/widl/ChangeLog
Modified: trunk/reactos/tools/widl/client.c
Modified: trunk/reactos/tools/widl/lex.yy.c
Modified: trunk/reactos/tools/widl/parser.l
Modified: trunk/reactos/tools/widl/parser.y
Modified: trunk/reactos/tools/widl/server.c
Modified: trunk/reactos/tools/widl/widltypes.h
Modified: trunk/reactos/tools/widl/y.tab.c
Modified: trunk/reactos/tools/widl/y.tab.h

Modified: trunk/reactos/tools/widl/ChangeLog
--- trunk/reactos/tools/widl/ChangeLog	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/ChangeLog	2005-04-03 12:49:25 UTC (rev 14474)
@@ -1,5 +1,15 @@
 ChangeLog
 
+2005-04-03 ekohl
+
+   tools/widl/client.c
+   tools/widl/parser.l
+   tools/widl/parser.y
+   tools/widl/server.c
+   tools/widl/widltypes.h
+
+Support 'ref' and 'unique' attributes for pointers.
+
 2005-03-27 Jacek Caban (from WINE)
 
   tools/widl/parser.y

Modified: trunk/reactos/tools/widl/client.c
--- trunk/reactos/tools/widl/client.c	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/client.c	2005-04-03 12:49:25 UTC (rev 14474)
@@ -187,6 +187,7 @@
     var_t *var;
     int out_attr;
     int string_attr;
+    int ptr_attr, ref_attr, unique_attr;
 
     print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
     print_client("{\n");
@@ -217,12 +218,27 @@
 
                 if (var->ptr_level == 1)
                 {
+                    ptr_attr = is_attr(var->attrs, ATTR_PTR);
+                    ref_attr = is_attr(var->attrs, ATTR_REF);
+                    unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+
+                    if (ptr_attr + ref_attr + unique_attr == 0)
+                        ref_attr = 1;
+
                     if (is_base_type(var->type))
                     {
                         if (out_attr)
                             print_client("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");
                         else
-                            print_client("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");
+                        {
+                            if (ptr_attr)
+                                print_client("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");
+                            else if (ref_attr)
+                                print_client("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");
+                            else if (unique_attr)
+                                print_client("0x12, 0x08,    /* FC_UP [simple_pointer] */\n");
+                        }
+
                         if (string_attr)
                         {
                             if (var->type->type == RPC_FC_CHAR)
@@ -268,6 +284,7 @@
     int out_attr;
     int string_attr;
     int nothing_printed = 1;
+    int ptr_attr, ref_attr, unique_attr;
     var_t *var;
     unsigned int local_type_offset = *type_offset;
 
@@ -286,19 +303,104 @@
             if (!out_attr && !in_attr)
                 in_attr = 1;
 
+            ptr_attr = is_attr(var->attrs, ATTR_PTR);
+            ref_attr = is_attr(var->attrs, ATTR_REF);
+            unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+
+            /* default to 'ref' attribute */
+            if (ptr_attr + ref_attr + unique_attr == 0)
+                ref_attr = 1;
+
             if (!in_attr)
                 continue;
 
-            if (var->ptr_level == 1 &&
-                string_attr &&
-                (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+            if (var->ptr_level == 1)
             {
-                size = 12;
-                alignment = 0;
-                if (last_size != -1)
-                    fprintf(client, " +");
-                fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
-                nothing_printed = 0;
+                if (unique_attr)
+                {
+                    if (string_attr &&
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+                    {
+                        size = 16;
+                        alignment = 0;
+                        if (last_size != -1)
+                            fprintf(client, " +");
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
+                        nothing_printed = 0;
+                    }
+                    else
+                    {
+                        size = 8;
+                        alignment = 0;
+                        if (last_size != -1)
+                            fprintf(client, " +");
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
+                        nothing_printed = 0;
+                    }
+                }
+                else if (ref_attr)
+                {
+                    if (string_attr &&
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+                    {
+                        size = 12;
+                        alignment = 0;
+                        if (last_size != -1)
+                            fprintf(client, " +");
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
+                        nothing_printed = 0;
+                    }
+                    else
+                    {
+                        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("%s:%d Unknown/unsupported type 0x%x\n",
+                                  __FUNCTION__,__LINE__, var->type->type);
+                            return;
+                        }
+
+                        if (last_size != -1)
+                            fprintf(client, " +");
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);
+                        nothing_printed = 0;
+                    }
+                }
             }
             else
             {
@@ -377,20 +479,46 @@
             if (!out_attr && !in_attr)
                 in_attr = 1;
 
+            ptr_attr = is_attr(var->attrs, ATTR_PTR);
+            ref_attr = is_attr(var->attrs, ATTR_REF);
+            unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+
+            /* default to 'ref' attribute */
+            if (ptr_attr + ref_attr + unique_attr == 0)
+                ref_attr = 1;
+
             if (in_attr)
             {
                 if (var->ptr_level == 1 &&
                     string_attr &&
                     (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
                 {
-                    print_client("NdrConformantStringBufferSize(\n");
-                    indent++;
-                    print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
-                    print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);
-                    print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
-                                 local_type_offset + 2);
-                    nothing_printed = 1;
-                    indent--;
+                    if (ptr_attr)
+                    {
+                        /* FIXME: not supported yet */
+                    }
+                    if (ref_attr)
+                    {
+                        print_client("NdrConformantStringBufferSize(\n");
+                        indent++;
+                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);
+                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
+                                     local_type_offset + 2);
+                        nothing_printed = 1;
+                        indent--;
+                    }
+                    else if (unique_attr)
+                    {
+                        print_client("NdrPointerBufferSize(\n");
+                        indent++;
+                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);
+                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
+                                     local_type_offset);
+                        nothing_printed = 1;
+                        indent--;
+                    }
                 }
             }
 
@@ -415,6 +543,7 @@
     int in_attr;
     int out_attr;
     int string_attr;
+    int ptr_attr, ref_attr, unique_attr;
     var_t *var;
 
     if (!func->args)
@@ -441,17 +570,103 @@
                 return;
             }
 
-            if (var->ptr_level == 1 &&
-                string_attr &&
-                (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+            if (var->ptr_level == 1)
             {
-                print_client("NdrConformantStringMarshall(\n");
-                indent++;
-                print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
-                print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);
-                print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n", *type_offset + 2);
-                indent--;
-                fprintf(client, "\n");
+                ptr_attr = is_attr(var->attrs, ATTR_PTR);
+                ref_attr = is_attr(var->attrs, ATTR_REF);
+                unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+                if (ptr_attr + ref_attr + unique_attr == 0)
+                    ref_attr = 1;
+
+                if (ref_attr)
+                {
+                    if (string_attr &&
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+                    {
+                        print_client("NdrConformantStringMarshall(\n");
+                        indent++;
+                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);
+                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n", *type_offset + 2);
+                        indent--;
+                        fprintf(client, "\n");
+                    }
+                    else
+                    {
+                        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("%s:%d Unknown/unsupported type 0x%x\n",
+                                  __FUNCTION__,__LINE__, var->type->type);
+                            return;
+                        }
+
+                        if (size != 0)
+                        {
+                            if (alignment != 0)
+                                print_client("_StubMsg.Buffer += %u;\n", alignment);
+
+                            print_client("*((");
+                            write_type(client, var->type, NULL, var->tname);
+                            fprintf(client, " __RPC_FAR*)_StubMsg.Buffer) = ");
+                            if (var->ptr_level == 1)
+                                fprintf(client, "*");
+                            write_name(client, var);
+                            fprintf(client, ";\n");
+                            print_client("_StubMsg.Buffer += sizeof(");
+                            write_type(client, var->type, NULL, var->tname);
+                            fprintf(client, ");\n");
+                            fprintf(client, "\n");
+
+                            last_size = size;
+                        }
+                    }
+                }
+                else if (unique_attr)
+                {
+                    print_client("NdrPointerMarshall(\n");
+                    indent++;
+                    print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+                    print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);
+                    print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n", *type_offset);
+                    indent--;
+                    fprintf(client, "\n");
+                }
             }
             else
             {
@@ -675,6 +890,9 @@
 static void check_pointers(func_t *func)
 {
     var_t *var;
+    int ptr_attr;
+    int ref_attr;
+    int unique_attr;
 
     if (!func->args)
         return;
@@ -683,20 +901,50 @@
     while (NEXT_LINK(var)) var = NEXT_LINK(var);
     while (var)
     {
-        if (var->ptr_level == 1)
+        ptr_attr = is_attr(var->attrs, ATTR_PTR);
+        ref_attr = is_attr(var->attrs, ATTR_REF);
+        unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+
+        if (var->ptr_level == 0)
         {
-            print_client("if (!%s)\n", var->name);
-            print_client("{\n");
-            indent++;
-            print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
-            indent--;
-            print_client("}\n");
-            fprintf(client, "\n");
+            if (ptr_attr + ref_attr + unique_attr != 0)
+            {
+                error("The attributes [ptr], [ref] and [unique] can only be used for pointers!\n");
+                return;
+            }
         }
-        else if (var->ptr_level > 1)
+        else
         {
-            error("Pointer level %d not supported!\n", var->ptr_level);
-            return;
+            /* default to 'ref' attribute */
+            if (ptr_attr + ref_attr + unique_attr == 0)
+            {
+              ref_attr = 1;
+            }
+
+            if (ptr_attr + ref_attr + unique_attr > 1)
+            {
+                error("The attributes [ptr], [ref] and [unique] are mutually exclusive!\n");
+                return;
+            }
+
+            if (var->ptr_level == 1)
+            {
+                if (ref_attr)
+                {
+                    print_client("if (!%s)\n", var->name);
+                    print_client("{\n");
+                    indent++;
+                    print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
+                    indent--;
+                    print_client("}\n");
+                    fprintf(client, "\n");
+                }
+            }
+            else if (var->ptr_level > 1)
+            {
+                error("Pointer level %d not supported!\n", var->ptr_level);
+                return;
+            }
         }
 
         var = PREV_LINK(var);

Modified: trunk/reactos/tools/widl/lex.yy.c
--- trunk/reactos/tools/widl/lex.yy.c	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/lex.yy.c	2005-04-03 12:49:25 UTC (rev 14474)
@@ -4555,6 +4555,7 @@
 	{"propput",			tPROPPUT},
 	{"propputref",			tPROPPUTREF},
 /* ... */
+	{"ptr",				tPTR},
 	{"public",			tPUBLIC},
 /* ... */
 	{"readonly",			tREADONLY},
@@ -4579,8 +4580,8 @@
 /* ... */
 	{"transmit_as",			tTRANSMITAS},
 	{"typedef",			tTYPEDEF},
+/* ... */
 	{"union",			tUNION},
-/* ... */
 	{"unique",			tUNIQUE},
 	{"unsigned",			tUNSIGNED},
 /* ... */

Modified: trunk/reactos/tools/widl/parser.l
--- trunk/reactos/tools/widl/parser.l	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/parser.l	2005-04-03 12:49:25 UTC (rev 14474)
@@ -275,6 +275,7 @@
 	{"propput",			tPROPPUT},
 	{"propputref",			tPROPPUTREF},
 /* ... */
+	{"ptr",				tPTR},
 	{"public",			tPUBLIC},
 /* ... */
 	{"readonly",			tREADONLY},
@@ -299,8 +300,8 @@
 /* ... */
 	{"transmit_as",			tTRANSMITAS},
 	{"typedef",			tTYPEDEF},
+/* ... */
 	{"union",			tUNION},
-/* ... */
 	{"unique",			tUNIQUE},
 	{"unsigned",			tUNSIGNED},
 /* ... */

Modified: trunk/reactos/tools/widl/parser.y
--- trunk/reactos/tools/widl/parser.y	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/parser.y	2005-04-03 12:49:25 UTC (rev 14474)
@@ -162,6 +162,7 @@
 %token tPOINTERDEFAULT
 %token tPROPERTIES
 %token tPROPGET tPROPPUT tPROPPUTREF
+%token tPTR
 %token tPUBLIC
 %token tREADONLY tREF
 %token tRESTRICTED
@@ -373,8 +374,10 @@
 	| tPROPGET				{ $$ = make_attr(ATTR_PROPGET); }
 	| tPROPPUT				{ $$ = make_attr(ATTR_PROPPUT); }
 	| tPROPPUTREF				{ $$ = make_attr(ATTR_PROPPUTREF); }
+	| tPTR					{ $$ = make_attr(ATTR_PTR); }
 	| tPUBLIC				{ $$ = make_attr(ATTR_PUBLIC); }
 	| tREADONLY				{ $$ = make_attr(ATTR_READONLY); }
+	| tREF					{ $$ = make_attr(ATTR_REF); }
 	| tRESTRICTED				{ $$ = make_attr(ATTR_RESTRICTED); }
 	| tRETVAL				{ $$ = make_attr(ATTR_RETVAL); }
 	| tSIZEIS '(' m_exprs ')'		{ $$ = make_attrp(ATTR_SIZEIS, $3); }
@@ -383,6 +386,7 @@
 	| tSWITCHIS '(' expr ')'		{ $$ = make_attrp(ATTR_SWITCHIS, $3); }
 	| tSWITCHTYPE '(' type ')'		{ $$ = make_attrp(ATTR_SWITCHTYPE, type_ref($3)); }
 	| tTRANSMITAS '(' type ')'		{ $$ = make_attrp(ATTR_TRANSMITAS, type_ref($3)); }
+	| tUNIQUE				{ $$ = make_attr(ATTR_UNIQUE); }
 	| tUUID '(' aUUID ')'			{ $$ = make_attrp(ATTR_UUID, $3); }
 	| tV1ENUM				{ $$ = make_attr(ATTR_V1ENUM); }
 	| tVARARG				{ $$ = make_attr(ATTR_VARARG); }

Modified: trunk/reactos/tools/widl/server.c
--- trunk/reactos/tools/widl/server.c	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/server.c	2005-04-03 12:49:25 UTC (rev 14474)
@@ -192,6 +192,7 @@
     var_t *var;
     int out_attr;
     int string_attr;
+    int ptr_attr, ref_attr, unique_attr;
 
     print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
     print_server("{\n");
@@ -222,12 +223,27 @@
 
                 if (var->ptr_level == 1)
                 {
+                    ptr_attr = is_attr(var->attrs, ATTR_PTR);
+                    ref_attr = is_attr(var->attrs, ATTR_REF);
+                    unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+
+                    if (ptr_attr + ref_attr + unique_attr == 0)
+                        ref_attr = 1;
+
                     if (is_base_type(var->type))
                     {
                         if (out_attr)
                             print_server("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");
                         else
-                            print_server("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");
+                        {
+                            if (ptr_attr)
+                                print_server("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");
+                            else if (ref_attr)
+                                print_server("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");
+                            else if (unique_attr)
+                                print_server("0x12, 0x08,    /* FC_UP [simple_pointer] */\n");
+                        }
+
                         if (string_attr)
                         {
                             if (var->type->type == RPC_FC_CHAR)
@@ -439,9 +455,9 @@
     unsigned int size;
     unsigned int last_size = 0;
     var_t *var;
-    int in_attr;
-    int out_attr;
+    int in_attr, out_attr;
     int string_attr;
+    int ptr_attr, ref_attr, unique_attr;
 
     if (!func->args)
         return;
@@ -460,18 +476,104 @@
 
         if (in_attr)
         {
-            if (var->ptr_level == 1 &&
-                string_attr &&
-                (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+            if (var->ptr_level == 1)
             {
-                print_server("NdrConformantStringUnmarshall(\n");
-                indent++;
-                print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
-                print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);
-                print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset + 2);
-                print_server("(unsigned char)0);\n");
-                indent--;
-                fprintf(server, "\n");
+                ptr_attr = is_attr(var->attrs, ATTR_PTR);
+                ref_attr = is_attr(var->attrs, ATTR_REF);
+                unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
+                if (ptr_attr + ref_attr + unique_attr == 0)
+                    ref_attr = 1;
+
+                if (ref_attr)
+                {
+                    if (string_attr &&
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
+                    {
+                        print_server("NdrConformantStringUnmarshall(\n");
+                        indent++;
+                        print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+                        print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);
+                        print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset + 2);
+                        print_server("(unsigned char)0);\n");
+                        indent--;
+                        fprintf(server, "\n");
+                    }
+                    else
+                    {
+                        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("%s:%d Unknown/unsupported type 0x%x\n",
+                                  __FUNCTION__,__LINE__, var->type->type);
+                            return;
+                        }
+
+                        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, NULL, var->tname);
+                            fprintf(server, " __RPC_FAR*)_StubMsg.Buffer;\n");
+                            print_server("_StubMsg.Buffer += sizeof(");
+                            write_type(server, var->type, NULL, var->tname);
+                            fprintf(server, ");\n");
+                            fprintf(server, "\n");
+
+                            last_size = size;
+                        }
+                    }
+                }
+                else if (unique_attr)
+                {
+                    print_server("NdrPointerUnmarshall(\n");
+                    indent++;
+                    print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
+                    print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);
+                    print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset);
+                    print_server("(unsigned char)0);\n");
+                    indent--;
+                    fprintf(server, "\n");
+                }
+
             }
             else
             {
@@ -523,35 +625,15 @@
                     if (alignment != 0)
                         print_server("_StubMsg.Buffer += %u;\n", alignment);
 
-                    if (var->ptr_level == 0)
-                    {
-                        print_server("");
-                        write_name(server, var);
-                        fprintf(server, " = *((");
-                        write_type(server, var->type, NULL, var->tname);
-                        fprintf(server, " __RPC_FAR*)_StubMsg.Buffer);\n");
-                        print_server("_StubMsg.Buffer += sizeof(");
-                        write_type(server, var->type, NULL, var->tname);
-                        fprintf(server, ");\n");
-                        fprintf(server, "\n");
-                    }
-                    else if (var->ptr_level == 1)
-                    {
-                        print_server("");
-                        write_name(server, var);
-                        fprintf(server, " = (");
-                        write_type(server, var->type, NULL, var->tname);
-                        fprintf(server, " __RPC_FAR*)_StubMsg.Buffer;\n");
-                        print_server("_StubMsg.Buffer += sizeof(");
-                        write_type(server, var->type, NULL, var->tname);
-                        fprintf(server, ");\n");
-                        fprintf(server, "\n");
-                    }
-                    else
-                    {
-                        error("Pointer level %d is not supported!\n", var->ptr_level);
-                        return;
-                    }
+                    print_server("");
+                    write_name(server, var);
+                    fprintf(server, " = *((");
+                    write_type(server, var->type, NULL, var->tname);
+                    fprintf(server, " __RPC_FAR*)_StubMsg.Buffer);\n");
+                    print_server("_StubMsg.Buffer += sizeof(");
+                    write_type(server, var->type, NULL, var->tname);
+                    fprintf(server, ");\n");
+                    fprintf(server, "\n");
 
                     last_size = size;
                 }

Modified: trunk/reactos/tools/widl/widltypes.h
--- trunk/reactos/tools/widl/widltypes.h	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/widltypes.h	2005-04-03 12:49:25 UTC (rev 14474)
@@ -98,8 +98,10 @@
     ATTR_PROPGET,
     ATTR_PROPPUT,
     ATTR_PROPPUTREF,
+    ATTR_PTR,
     ATTR_PUBLIC,
     ATTR_READONLY,
+    ATTR_REF,
     ATTR_RESTRICTED,
     ATTR_RETVAL,
     ATTR_SIZEIS,
@@ -108,6 +110,7 @@
     ATTR_SWITCHIS,
     ATTR_SWITCHTYPE,
     ATTR_TRANSMITAS,
+    ATTR_UNIQUE,
     ATTR_UUID,
     ATTR_V1ENUM,
     ATTR_VARARG,

Modified: trunk/reactos/tools/widl/y.tab.c
--- trunk/reactos/tools/widl/y.tab.c	2005-04-03 12:14:30 UTC (rev 14473)
+++ trunk/reactos/tools/widl/y.tab.c	2005-04-03 12:49:25 UTC (rev 14474)
@@ -91,40 +91,41 @@
 #define	tPROPGET	341
 #define	tPROPPUT	342
 #define	tPROPPUTREF	343
-#define	tPUBLIC	344
-#define	tREADONLY	345
-#define	tREF	346
-#define	tRESTRICTED	347
-#define	tRETVAL	348
-#define	tSHORT	349
-#define	tSIGNED	350
-#define	tSIZEIS	351
-#define	tSIZEOF	352
-#define	tSMALL	353
-#define	tSOURCE	354
-#define	tSTDCALL	355
-#define	tSTRING	356
-#define	tSTRUCT	357
-#define	tSWITCH	358
-#define	tSWITCHIS	359
-#define	tSWITCHTYPE	360
-#define	tTRANSMITAS	361
-#define	tTYPEDEF	362
-#define	tUNION	363
-#define	tUNIQUE	364
-#define	tUNSIGNED	365
-#define	tUUID	366
-#define	tV1ENUM	367
-#define	tVARARG	368
-#define	tVERSION	369
-#define	tVOID	370
-#define	tWCHAR	371
-#define	tWIREMARSHAL	372
-#define	tPOINTERTYPE	373
-#define	COND	374
-#define	CAST	375
-#define	PPTR	376
-#define	NEG	377
+#define	tPTR	344
+#define	tPUBLIC	345
+#define	tREADONLY	346
+#define	tREF	347
+#define	tRESTRICTED	348
+#define	tRETVAL	349
+#define	tSHORT	350
+#define	tSIGNED	351
+#define	tSIZEIS	352
+#define	tSIZEOF	353
+#define	tSMALL	354
+#define	tSOURCE	355
+#define	tSTDCALL	356
+#define	tSTRING	357
+#define	tSTRUCT	358
+#define	tSWITCH	359
+#define	tSWITCHIS	360
+#define	tSWITCHTYPE	361
+#define	tTRANSMITAS	362
+#define	tTYPEDEF	363
+#define	tUNION	364
+#define	tUNIQUE	365
+#define	tUNSIGNED	366
+#define	tUUID	367
+#define	tV1ENUM	368
+#define	tVARARG	369
+#define	tVERSION	370
+#define	tVOID	371
+#define	tWCHAR	372
+#define	tWIREMARSHAL	373
+#define	tPOINTERTYPE	374
+#define	COND	375
+#define	CAST	376
+#define	PPTR	377
+#define	NEG	378
 
 #line 1 "parser.y"
 
@@ -256,26 +257,26 @@
 
 
 
-#define	YYFINAL		459
+#define	YYFINAL		462
 #define	YYFLAG		-32768
-#define	YYNTBASE	143
+#define	YYNTBASE	144
 
-#define YYTRANSLATE(x) ((unsigned)(x) <= 377 ? yytranslate[x] : 215)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 378 ? yytranslate[x] : 216)
 
 static const short yytranslate[] = {     0,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,   123,     2,   133,
-   134,   126,   125,   120,   124,   142,   127,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,   139,   132,     2,
-   140,     2,   141,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,   124,     2,   134,
+   135,   127,   126,   121,   125,   143,   128,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,   140,   133,     2,
+   141,     2,   142,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-   137,     2,   138,     2,     2,     2,     2,     2,     2,     2,
+   138,     2,   139,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,   135,   122,   136,   128,     2,     2,     2,     2,
+     2,     2,   136,   123,   137,   129,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -300,7 +301,7 @@
     87,    88,    89,    90,    91,    92,    93,    94,    95,    96,
     97,    98,    99,   100,   101,   102,   103,   104,   105,   106,
    107,   108,   109,   110,   111,   112,   113,   114,   115,   116,
-   117,   118,   119,   121,   129,   130,   131
+   117,   118,   119,   120,   122,   130,   131,   132
 };
 
 #if YYDEBUG != 0
@@ -315,132 +316,133 @@
    222,   224,   226,   231,   236,   241,   246,   251,   253,   258,
    260,   265,   271,   273,   275,   280,   282,   284,   286,   288,
    290,   292,   294,   299,   301,   303,   305,   307,   309,   311,
-   313,   318,   320,   322,   327,   332,   337,   342,   344,   346,
-   351,   356,   358,   359,   361,   362,   365,   370,   374,   380,
-   381,   384,   386,   388,   392,   396,   398,   404,   406,   410,
-   411,   413,   415,   417,   419,   425,   429,   433,   437,   441,
-   445,   449,   453,   457,   460,   463,   466,   471,   476,   480,
-   482,   486,   488,   493,   494,   497,   500,   504,   507,   509,
-   514,   522,   523,   525,   526,   528,   530,   532,   534,   536,
-   538,   540,   542,   544,   546,   549,   552,   554,   556,   558,
-   560,   562,   564,   565,   567,   569,   572,   575,   578,   581,
-   583,   585,   588,   591,   594,   599,   600,   603,   606,   609,
-   612,   615,   618,   622,   625,   629,   635,   636,   639,   642,
-   645,   648,   654,   662,   664,   667,   670,   673,   676,   679,
-   684,   687,   690,   692,   694,   698,   700,   704,   706,   708,
-   714,   716,   718,   720,   723,   725,   728,   730,   733,   735,
-   738,   743,   749,   760,   762
+   313,   315,   317,   322,   324,   326,   331,   336,   341,   343,
+   348,   350,   352,   357,   362,   364,   365,   367,   368,   371,
+   376,   380,   386,   387,   390,   392,   394,   398,   402,   404,
+   410,   412,   416,   417,   419,   421,   423,   425,   431,   435,
+   439,   443,   447,   451,   455,   459,   463,   466,   469,   472,
+   477,   482,   486,   488,   492,   494,   499,   500,   503,   506,
+   510,   513,   515,   520,   528,   529,   531,   532,   534,   536,
+   538,   540,   542,   544,   546,   548,   550,   552,   555,   558,
+   560,   562,   564,   566,   568,   570,   571,   573,   575,   578,
+   581,   584,   587,   589,   591,   594,   597,   600,   605,   606,
+   609,   612,   615,   618,   621,   624,   628,   631,   635,   641,
+   642,   645,   648,   651,   654,   660,   668,   670,   673,   676,
+   679,   682,   685,   690,   693,   696,   698,   700,   704,   706,
+   710,   712,   714,   720,   722,   724,   726,   729,   731,   734,
+   736,   739,   741,   744,   749,   755,   766,   768
 };
 
-static const short yyrhs[] = {   144,
-     0,     0,   144,   202,     0,   144,   201,     0,   144,   190,
-     0,   144,   205,     0,   144,   153,     0,   144,   147,     0,
-     0,   145,   202,     0,   145,   201,     0,   145,   190,     0,
-   145,   205,     0,   145,   147,     0,     0,   146,   181,   132,
-     0,   146,   147,     0,   132,     0,   167,   132,     0,   148,
-     0,   171,   132,     0,   177,   132,     0,   150,     0,   210,
-   132,     0,   212,   132,     0,   213,   132,     0,    37,   133,
-     7,   134,     0,    64,     7,   132,     0,   149,   145,     9,
-     0,    74,     3,     0,   161,   151,   135,     0,   152,   145,
-   136,     0,     0,   156,     0,   116,     0,   157,     0,   156,
-   120,   157,     0,   155,     0,   161,   211,   207,   158,     0,
-   211,   207,   158,     0,   161,   211,   207,   133,   154,   134,
-     0,   211,   207,   133,   154,   134,     0,     0,   137,   159,
-   138,     0,   137,   126,   138,     0,   173,     0,   159,   120,
-   174,     0,   159,   138,   137,   174,     0,     0,   161,     0,
-   137,   162,   138,     0,   163,     0,   162,   120,   163,     0,
-   162,   138,   137,   163,     0,    16,     0,    18,     0,    24,
-   133,   184,   134,     0,    26,   133,   175,   134,     0,    33,
+static const short yyrhs[] = {   145,
+     0,     0,   145,   203,     0,   145,   202,     0,   145,   191,
+     0,   145,   206,     0,   145,   154,     0,   145,   148,     0,
+     0,   146,   203,     0,   146,   202,     0,   146,   191,     0,
+   146,   206,     0,   146,   148,     0,     0,   147,   182,   133,
+     0,   147,   148,     0,   133,     0,   168,   133,     0,   149,
+     0,   172,   133,     0,   178,   133,     0,   151,     0,   211,
+   133,     0,   213,   133,     0,   214,   133,     0,    37,   134,
+     7,   135,     0,    64,     7,   133,     0,   150,   146,     9,
+     0,    74,     3,     0,   162,   152,   136,     0,   153,   146,
+   137,     0,     0,   157,     0,   117,     0,   158,     0,   157,
+   121,   158,     0,   156,     0,   162,   212,   208,   159,     0,
+   212,   208,   159,     0,   162,   212,   208,   134,   155,   135,
+     0,   212,   208,   134,   155,   135,     0,     0,   138,   160,
+   139,     0,   138,   127,   139,     0,   174,     0,   160,   121,
+   175,     0,   160,   139,   138,   175,     0,     0,   162,     0,
+   138,   163,   139,     0,   164,     0,   163,   121,   164,     0,
+   163,   139,   138,   164,     0,    16,     0,    18,     0,    24,
+   134,   185,   135,     0,    26,   134,   176,   135,     0,    33,
      0,    34,     0,    35,     0,    36,     0,    38,     0,    39,
-   133,   176,   134,     0,    39,   133,     7,   134,     0,    41,
-   133,     7,   134,     0,    43,     0,    44,   133,     7,   134,
-     0,    45,   133,     7,   134,     0,    45,   133,   176,   134,
-     0,    48,     0,    51,     0,    53,   133,   176,   134,     0,
-    54,   133,     7,   134,     0,    55,   133,     7,   134,     0,
-    56,   133,   176,   134,     0,    57,   133,     7,   134,     0,
-    58,     0,    60,   133,   176,   134,     0,    61,     0,    62,
-   133,   184,   134,     0,    63,   133,    52,     3,   134,     0,
-    66,     0,    69,     0,    73,   133,   172,   134,     0,    75,
+   134,   177,   135,     0,    39,   134,     7,   135,     0,    41,
+   134,     7,   135,     0,    43,     0,    44,   134,     7,   135,
+     0,    45,   134,     7,   135,     0,    45,   134,   177,   135,
+     0,    48,     0,    51,     0,    53,   134,   177,   135,     0,
+    54,   134,     7,   135,     0,    55,   134,     7,   135,     0,
+    56,   134,   177,   135,     0,    57,   134,     7,   135,     0,
+    58,     0,    60,   134,   177,   135,     0,    61,     0,    62,
+   134,   185,   135,     0,    63,   134,    52,     3,   135,     0,
+    66,     0,    69,     0,    73,   134,   173,   135,     0,    75,
      0,    79,     0,    80,     0,    81,     0,    82,     0,    83,
-     0,    84,     0,    85,   133,   209,   134,     0,    87,     0,
-    88,     0,    89,     0,    90,     0,    91,     0,    93,     0,
-    94,     0,    97,   133,   172,   134,     0,   100,     0,   102,
-     0,   105,   133,   174,   134,     0,   106,   133,   211,   134,
-     0,   107,   133,   211,   134,     0,   112,   133,     8,   134,
-     0,   113,     0,   114,     0,   115,   133,   214,   134,     0,
-   118,   133,   211,   134,     0,   209,     0,     0,   101,     0,
-     0,   165,   166,     0,    26,   174,   139,   179,     0,    38,
-   139,   179,     0,    32,   211,   184,   140,   176,     0,     0,
-   169,   120,     0,   169,     0,   170,     0,   169,   120,   170,
-     0,   184,   140,   176,     0,   184,     0,    46,   183,   135,
-   168,   136,     0,   173,     0,   172,   120,   173,     0,     0,
-   174,     0,     5,     0,     6,     0,     3,     0,   174,   141,
-   174,   139,   174,     0,   174,   122,   174,     0,   174,   123,
-   174,     0,   174,   125,   174,     0,   174,   124,   174,     0,
-   174,   126,   174,     0,   174,   127,   174,     0,   174,    10,
-   174,     0,   174,    11,   174,     0,   128,   174,     0,   124,
-   174,     0,   126,   174,     0,   133,   211,   134,   174,     0,
-    98,   133,   211,   134,     0,   133,   174,   134,     0,   176,
-     0,   175,   120,   176,     0,   174,     0,    49,    32,   211,
-   184,     0,     0,   178,   179,     0,   180,   132,     0,   160,
-   213,   132,     0,   161,   132,     0,   132,     0,   160,   211,
-   207,   158,     0,   160,   211,   164,   207,   133,   154,   134,
-     0,     0,   184,     0,     0,     3,     0,     4,     0,     3,
-     0,     4,     0,    60,     0,    94,     0,   115,     0,    22,
-     0,   117,     0,   187,     0,    96,   187,     0,   111,   187,
-     0,   111,     0,    50,     0,    42,     0,    20,     0,    47,
-     0,    52,     0,     0,    70,     0,    70,     0,    99,   186,
-     0,    95,   186,     0,    76,   186,     0,    59,   186,     0,
-    71,     0,    28,     0,    29,     3,     0,    29,     4,     0,
-   161,   188,     0,   189,   135,   191,   136,     0,     0,   191,
-   192,     0,   160,   202,     0,    40,     3,     0,    40,     4,
-     0,   161,   193,     0,    86,   139,     0,   195,   180,   132,
-     0,    77,   139,     0,   196,   181,   132,     0,   194,   135,
-   195,   196,   136,     0,     0,   139,     4,     0,    72,     3,
-     0,    72,     4,     0,   161,   199,     0,   200,   198,   135,
-   146,   136,     0,   200,   139,     3,   135,   150,   146,   136,
[truncated at 1000 lines; 2291 more skipped]