sync rpc4rt winetests as well
authorChristoph von Wittich <christoph_vw@reactos.org>
Sat, 13 Sep 2008 16:18:44 +0000 (16:18 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sat, 13 Sep 2008 16:18:44 +0000 (16:18 +0000)
svn path=/trunk/; revision=36189

rostests/winetests/rpcrt4/cstub.c
rostests/winetests/rpcrt4/generated.c
rostests/winetests/rpcrt4/ndr_marshall.c
rostests/winetests/rpcrt4/rpc.c
rostests/winetests/rpcrt4/server.c
rostests/winetests/rpcrt4/server.idl

index a47fa6e..37b5985 100644 (file)
@@ -30,6 +30,7 @@
 #include <winerror.h>
 
 
+#include "initguid.h"
 #include "rpc.h"
 #include "rpcdce.h"
 #include "rpcproxy.h"
index b281d0b..609e49c 100644 (file)
@@ -308,12 +308,12 @@ static void test_pack_ARRAY_INFO(void)
 {
     /* ARRAY_INFO (pack 4) */
     TEST_TYPE(ARRAY_INFO, 24, 4);
-    TEST_FIELD(ARRAY_INFO, long, Dimension, 0, 4, 4);
-    TEST_FIELD(ARRAY_INFO, unsigned long *, BufferConformanceMark, 4, 4, 4);
-    TEST_FIELD(ARRAY_INFO, unsigned long *, BufferVarianceMark, 8, 4, 4);
-    TEST_FIELD(ARRAY_INFO, unsigned long *, MaxCountArray, 12, 4, 4);
-    TEST_FIELD(ARRAY_INFO, unsigned long *, OffsetArray, 16, 4, 4);
-    TEST_FIELD(ARRAY_INFO, unsigned long *, ActualCountArray, 20, 4, 4);
+    TEST_FIELD(ARRAY_INFO, LONG, Dimension, 0, 4, 4);
+    TEST_FIELD(ARRAY_INFO, ULONG *, BufferConformanceMark, 4, 4, 4);
+    TEST_FIELD(ARRAY_INFO, ULONG *, BufferVarianceMark, 8, 4, 4);
+    TEST_FIELD(ARRAY_INFO, ULONG *, MaxCountArray, 12, 4, 4);
+    TEST_FIELD(ARRAY_INFO, ULONG *, OffsetArray, 16, 4, 4);
+    TEST_FIELD(ARRAY_INFO, ULONG *, ActualCountArray, 20, 4, 4);
 }
 
 static void test_pack_COMM_FAULT_OFFSETS(void)
@@ -328,8 +328,8 @@ static void test_pack_CS_STUB_INFO(void)
 {
     /* CS_STUB_INFO (pack 4) */
     TEST_TYPE(CS_STUB_INFO, 12, 4);
-    TEST_FIELD(CS_STUB_INFO, unsigned long, WireCodeset, 0, 4, 4);
-    TEST_FIELD(CS_STUB_INFO, unsigned long, DesiredReceivingCodeset, 4, 4, 4);
+    TEST_FIELD(CS_STUB_INFO, ULONG, WireCodeset, 0, 4, 4);
+    TEST_FIELD(CS_STUB_INFO, ULONG, DesiredReceivingCodeset, 4, 4, 4);
     TEST_FIELD(CS_STUB_INFO, void *, CSArrayInfo, 8, 4, 4);
 }
 
@@ -344,7 +344,7 @@ static void test_pack_FULL_PTR_TO_REFID_ELEMENT(void)
     TEST_TYPE(FULL_PTR_TO_REFID_ELEMENT, 16, 4);
     TEST_FIELD(FULL_PTR_TO_REFID_ELEMENT, struct _FULL_PTR_TO_REFID_ELEMENT *, Next, 0, 4, 4);
     TEST_FIELD(FULL_PTR_TO_REFID_ELEMENT, void *, Pointer, 4, 4, 4);
-    TEST_FIELD(FULL_PTR_TO_REFID_ELEMENT, unsigned long, RefId, 8, 4, 4);
+    TEST_FIELD(FULL_PTR_TO_REFID_ELEMENT, ULONG, RefId, 8, 4, 4);
     TEST_FIELD(FULL_PTR_TO_REFID_ELEMENT, unsigned char, State, 12, 1, 1);
 }
 
@@ -404,20 +404,19 @@ static void test_pack_MIDL_STUB_MESSAGE(void)
     TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char *, BufferStart, 8, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char *, BufferEnd, 12, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char *, BufferMark, 16, 4, 4);
-    TEST_FIELD(MIDL_STUB_MESSAGE, unsigned long, BufferLength, 20, 4, 4);
-    TEST_FIELD(MIDL_STUB_MESSAGE, unsigned long, MemorySize, 24, 4, 4);
+    TEST_FIELD(MIDL_STUB_MESSAGE, ULONG, BufferLength, 20, 4, 4);
+    TEST_FIELD(MIDL_STUB_MESSAGE, ULONG, MemorySize, 24, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char *, Memory, 28, 4, 4);
-    TEST_FIELD(MIDL_STUB_MESSAGE, int, IsClient, 32, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, int, ReuseBuffer, 36, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, struct NDR_ALLOC_ALL_NODES_CONTEXT *, pAllocAllNodesContext, 40, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, struct NDR_POINTER_QUEUE_STATE *, pPointerQueueState, 44, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, int, IgnoreEmbeddedPointers, 48, 4, 4);
     TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char *, PointerBufferMark, 52, 4, 4);
-    TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char, fBufferValid, 56, 1, 1);
+    TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char, CorrDespIncrement, 56, 1, 1);
     TEST_FIELD(MIDL_STUB_MESSAGE, unsigned char, uFlags, 57, 1, 1);
     TEST_FIELD(MIDL_STUB_MESSAGE, ULONG_PTR, MaxCount, 60, 4, 4);
-    TEST_FIELD(MIDL_STUB_MESSAGE, unsigned long, Offset, 64, 4, 4);
-    TEST_FIELD(MIDL_STUB_MESSAGE, unsigned long, ActualCount, 68, 4, 4);
+    TEST_FIELD(MIDL_STUB_MESSAGE, ULONG, Offset, 64, 4, 4);
+    TEST_FIELD(MIDL_STUB_MESSAGE, ULONG, ActualCount, 68, 4, 4);
 }
 
 static void test_pack_MIDL_STUBLESS_PROXY_INFO(void)
@@ -464,6 +463,19 @@ static void test_pack_NDR_SCONTEXT(void)
     TEST_TYPE(NDR_SCONTEXT, 4, 4);
 }
 
+static void test_pack_NDR_USER_MARSHAL_INFO(void)
+{
+    /* NDR_USER_MARSHAL_INFO (pack 4) */
+    TEST_FIELD(NDR_USER_MARSHAL_INFO, ULONG, InformationLevel, 0, 4, 4);
+}
+
+static void test_pack_NDR_USER_MARSHAL_INFO_LEVEL1(void)
+{
+    /* NDR_USER_MARSHAL_INFO_LEVEL1 (pack 4) */
+    TEST_FIELD(NDR_USER_MARSHAL_INFO_LEVEL1, void *, Buffer, 0, 4, 4);
+    TEST_FIELD(NDR_USER_MARSHAL_INFO_LEVEL1, ULONG, BufferSize, 4, 4, 4);
+}
+
 static void test_pack_PARRAY_INFO(void)
 {
     /* PARRAY_INFO */
@@ -563,7 +575,7 @@ static void test_pack_SCONTEXT_QUEUE(void)
 {
     /* SCONTEXT_QUEUE (pack 4) */
     TEST_TYPE(SCONTEXT_QUEUE, 8, 4);
-    TEST_FIELD(SCONTEXT_QUEUE, unsigned long, NumberOfObjects, 0, 4, 4);
+    TEST_FIELD(SCONTEXT_QUEUE, ULONG, NumberOfObjects, 0, 4, 4);
     TEST_FIELD(SCONTEXT_QUEUE, NDR_SCONTEXT *, ArrayOfObjects, 4, 4, 4);
 }
 
@@ -580,10 +592,10 @@ static void test_pack_STUB_THUNK(void)
 static void test_pack_USER_MARSHAL_CB(void)
 {
     /* USER_MARSHAL_CB (pack 4) */
-    TEST_FIELD(USER_MARSHAL_CB, unsigned long, Flags, 0, 4, 4);
+    TEST_FIELD(USER_MARSHAL_CB, ULONG, Flags, 0, 4, 4);
     TEST_FIELD(USER_MARSHAL_CB, PMIDL_STUB_MESSAGE, pStubMsg, 4, 4, 4);
     TEST_FIELD(USER_MARSHAL_CB, PFORMAT_STRING, pReserve, 8, 4, 4);
-    TEST_FIELD(USER_MARSHAL_CB, unsigned long, Signature, 12, 4, 4);
+    TEST_FIELD(USER_MARSHAL_CB, ULONG, Signature, 12, 4, 4);
 }
 
 static void test_pack_USER_MARSHAL_FREEING_ROUTINE(void)
@@ -649,6 +661,8 @@ static void test_pack(void)
     test_pack_NDR_NOTIFY_ROUTINE();
     test_pack_NDR_RUNDOWN();
     test_pack_NDR_SCONTEXT();
+    test_pack_NDR_USER_MARSHAL_INFO();
+    test_pack_NDR_USER_MARSHAL_INFO_LEVEL1();
     test_pack_PARRAY_INFO();
     test_pack_PFORMAT_STRING();
     test_pack_PFULL_PTR_TO_REFID_ELEMENT();
index 1ff5e3b..3cd1337 100644 (file)
@@ -97,6 +97,41 @@ static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface =
 };
 
 static RPC_IF_HANDLE IFoo_v0_0_s_ifspec = (RPC_IF_HANDLE)& IFoo___RpcServerInterface;
+static BOOL use_pointer_ids = FALSE;
+
+static void determine_pointer_marshalling_style(void)
+{
+    RPC_MESSAGE RpcMessage;
+    MIDL_STUB_MESSAGE StubMsg;
+    MIDL_STUB_DESC StubDesc;
+    char ch = 0xde;
+
+    static const unsigned char fmtstr_up_char[] =
+    {
+        0x12, 0x8,      /* FC_UP [simple_pointer] */
+        0x2,            /* FC_CHAR */
+        0x5c,           /* FC_PAD */
+    };
+
+    StubDesc = Object_StubDesc;
+    StubDesc.pFormatTypes = NULL;
+
+    NdrClientInitializeNew(
+                           &RpcMessage,
+                           &StubMsg,
+                           &StubDesc,
+                           0);
+
+    StubMsg.BufferLength = 8;
+    StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
+    NdrPointerMarshall(&StubMsg, (unsigned char*)&ch, fmtstr_up_char);
+    ok(StubMsg.Buffer == StubMsg.BufferStart + 5, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart);
+
+    use_pointer_ids = (*(unsigned int *)StubMsg.BufferStart != (unsigned int)&ch);
+    trace("Pointer marshalling using %s\n", use_pointer_ids ? "pointer ids" : "pointer value");
+
+    HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart);
+}
 
 static void test_ndr_simple_type(void)
 {
@@ -423,8 +458,11 @@ static void test_simple_types(void)
 
     ch = 0xa5;
     ch_ptr = &ch;
-    *(void**)wiredata = ch_ptr;
-    wiredata[sizeof(void*)] = ch;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)ch_ptr;
+    wiredata[4] = ch;
  
     test_pointer_marshal(fmtstr_up_char, ch_ptr, 1, wiredata, 5, NULL, 0, "up_char");
     test_pointer_marshal(fmtstr_up_byte, ch_ptr, 1, wiredata, 5, NULL, 0, "up_byte");
@@ -437,21 +475,30 @@ static void test_simple_types(void)
     test_pointer_marshal(fmtstr_rpup_char2, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char2");
 
     s = 0xa597;
-    *(void**)wiredata = &s;
-    *(unsigned short*)(wiredata + sizeof(void*)) = s;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&s;
+    *(unsigned short*)(wiredata + 4) = s;
 
     test_pointer_marshal(fmtstr_up_wchar, &s, 2, wiredata, 6, NULL, 0, "up_wchar");
     test_pointer_marshal(fmtstr_up_short, &s, 2, wiredata, 6, NULL, 0, "up_short");
     test_pointer_marshal(fmtstr_up_ushort, &s, 2, wiredata, 6, NULL, 0, "up_ushort");
 
     i = 0x7fff;
-    *(void**)wiredata = &i;
-    *(unsigned short*)(wiredata + sizeof(void*)) = i;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&i;
+    *(unsigned short*)(wiredata + 4) = i;
     test_pointer_marshal(fmtstr_up_enum16, &i, 2, wiredata, 6, NULL, 0, "up_enum16");
 
     l = 0xcafebabe;
-    *(void**)wiredata = &l;
-    *(unsigned long*)(wiredata + sizeof(void*)) = l;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&l;
+    *(unsigned long*)(wiredata + 4) = l;
 
     test_pointer_marshal(fmtstr_up_long, &l, 4, wiredata, 8, NULL, 0, "up_long");
     test_pointer_marshal(fmtstr_up_ulong, &l, 4, wiredata, 8, NULL, 0,  "up_ulong");
@@ -459,20 +506,29 @@ static void test_simple_types(void)
     test_pointer_marshal(fmtstr_up_errorstatus, &l, 4, wiredata, 8, NULL, 0,  "up_errorstatus");
 
     ll = ((ULONGLONG)0xcafebabe) << 32 | 0xdeadbeef;
-    *(void**)wiredata = &ll;
-    *(void**)(wiredata + sizeof(void*)) = NULL;
-    *(ULONGLONG*)(wiredata + 2 * sizeof(void*)) = ll;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&ll;
+    *(unsigned int **)(wiredata + 4) = 0;
+    *(ULONGLONG*)(wiredata + 8) = ll;
     test_pointer_marshal(fmtstr_up_longlong, &ll, 8, wiredata, 16, NULL, 0, "up_longlong");
 
     f = 3.1415f;
-    *(void**)wiredata = &f;
-    *(float*)(wiredata + sizeof(void*)) = f;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&f;
+    *(float*)(wiredata + 4) = f;
     test_pointer_marshal(fmtstr_up_float, &f, 4, wiredata, 8, NULL, 0, "up_float");
 
     d = 3.1415;
-    *(void**)wiredata = &d;
-    *(void**)(wiredata + sizeof(void*)) = NULL;
-    *(double*)(wiredata + 2 * sizeof(void*)) = d;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&d;
+    *(unsigned int *)(wiredata + 4) = 0;
+    *(double*)(wiredata + 8) = d;
     test_pointer_marshal(fmtstr_up_double, &d, 8, wiredata, 16, NULL, 0,  "up_double");
 
 }
@@ -877,6 +933,9 @@ static void test_simple_struct(void)
 
     };
 
+    /* zero the entire structure, including the holes */
+    memset(&s1, 0, sizeof(s1));
+
     /* FC_STRUCT */
     s1.s = 0x1234;
     s1.c = 0xa5;
@@ -888,7 +947,10 @@ static void test_simple_struct(void)
     memcpy(wiredata, &s1, wiredatalen); 
     test_simple_struct_marshal(fmtstr_simple_struct + 4, &s1, 24, wiredata, 24, NULL, 0, "struct");
 
-    *(void**)wiredata = &s1;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&s1;
     memcpy(wiredata + 4, &s1, wiredatalen);
     if (0)
     {
@@ -896,18 +958,34 @@ static void test_simple_struct(void)
     test_pointer_marshal(fmtstr_simple_struct, &s1, 24, wiredata, 28, NULL, 0, "struct");
     }
 
+    /* zero the entire structure, including the hole */
+    memset(&ps1, 0, sizeof(ps1));
+
     /* FC_PSTRUCT */
     ps1.l1 = 0xdeadbeef;
     l = 0xcafebabe;
     ps1.pl1 = &l;
     c = 'a';
     ps1.pc1 = &c;
-    memcpy(wiredata + 4, &ps1, 12);
+    *(unsigned int *)(wiredata + 4) = 0xdeadbeef;
+    if (use_pointer_ids)
+    {
+       *(unsigned int *)(wiredata + 8) = 0x20000;
+       *(unsigned int *)(wiredata + 12) = 0x20004;
+    }
+    else
+    {
+       *(unsigned int *)(wiredata + 8) = (unsigned int)&l;
+       *(unsigned int *)(wiredata + 12) = (unsigned int)&c;
+    }
     memcpy(wiredata + 16, &l, 4);
     memcpy(wiredata + 20, &c, 1);
 
     test_simple_struct_marshal(fmtstr_pointer_struct + 4, &ps1, 17, wiredata + 4, 17, ps1_cmp, 2, "pointer_struct");
-    *(void**)wiredata = &ps1;
+    if (use_pointer_ids)
+        *(unsigned int *)wiredata = 0x20000;
+    else
+        *(unsigned int *)wiredata = (unsigned int)&ps1;
     if (0)
     {
     /* one of the unmarshallings crashes Wine */
@@ -1083,10 +1161,12 @@ static void test_client_init(void)
     ok(stubMsg.IsClient == 1, "stubMsg.IsClient should have been 1 instead of %u\n", stubMsg.IsClient);
     TEST_ZERO(ReuseBuffer, "%d");
     TEST_ZERO(pAllocAllNodesContext, "%p");
-    TEST_ZERO(pPointerQueueState, "%p");
+    ok(stubMsg.pPointerQueueState == 0 ||
+       broken(stubMsg.pPointerQueueState == (void *)0xcccccccc), /* win2k */
+       "stubMsg.pPointerQueueState should have been unset instead of %p\n", stubMsg.pPointerQueueState);
     TEST_ZERO(IgnoreEmbeddedPointers, "%d");
     TEST_ZERO(PointerBufferMark, "%p");
-    TEST_ZERO(fBufferValid, "%d");
+    TEST_ZERO(CorrDespIncrement, "%d");
     TEST_ZERO(uFlags, "%d");
     /* FIXME: UniquePtrCount */
     TEST_ULONG_PTR_UNSET(MaxCount);
@@ -1104,12 +1184,23 @@ static void test_client_init(void)
     TEST_ZERO(PointerLength, "%d");
     TEST_ZERO(fInDontFree, "%d");
     TEST_ZERO(fDontCallFreeInst, "%d");
-    TEST_ZERO(fInOnlyParam, "%d");
+    ok(stubMsg.fInOnlyParam == 0 ||
+       stubMsg.fInOnlyParam == -1, /* Vista */
+       "fInOnlyParam should have been set to 0 or -1 instead of %d\n", stubMsg.fInOnlyParam);
     TEST_ZERO(fHasReturn, "%d");
     TEST_ZERO(fHasExtensions, "%d");
     TEST_ZERO(fHasNewCorrDesc, "%d");
-    TEST_ZERO(fUnused, "%d");
-    ok(stubMsg.fUnused2 == 0xffffcccc, "stubMsg.fUnused2 should have been 0xcccc instead of 0x%x\n", stubMsg.fUnused2);
+    TEST_ZERO(fIsIn, "%d");
+    TEST_ZERO(fIsOut, "%d");
+    TEST_ZERO(fIsOicf, "%d");
+    TEST_ZERO(fBufferValid, "%d");
+    TEST_ZERO(fHasMemoryValidateCallback, "%d");
+    TEST_ZERO(fInFree, "%d");
+    TEST_ZERO(fNeedMCCP, "%d");
+    ok(stubMsg.fUnused == 0 ||
+       stubMsg.fUnused == -2, /* Vista */
+       "fUnused should have been set to 0 or -2 instead of %d\n", stubMsg.fUnused);
+    ok(stubMsg.fUnused2 == 0xffffcccc, "stubMsg.fUnused2 should have been 0xffffcccc instead of 0x%x\n", stubMsg.fUnused2);
     ok(stubMsg.dwDestContext == MSHCTX_DIFFERENTMACHINE, "stubMsg.dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n", stubMsg.dwDestContext);
     TEST_ZERO(pvDestContext, "%p");
     TEST_POINTER_UNSET(SavedContextHandles);
@@ -1175,12 +1266,18 @@ todo_wine
     TEST_ULONG_UNSET(MemorySize);
     TEST_POINTER_UNSET(Memory);
     ok(stubMsg.IsClient == 0, "stubMsg.IsClient should have been 0 instead of %u\n", stubMsg.IsClient);
-    TEST_ZERO(ReuseBuffer, "%d");
+    ok(stubMsg.ReuseBuffer == 0 ||
+       broken(stubMsg.ReuseBuffer == 1), /* win2k */
+       "stubMsg.ReuseBuffer should have been set to zero instead of %d\n", stubMsg.ReuseBuffer);
     TEST_ZERO(pAllocAllNodesContext, "%p");
-    TEST_ZERO(pPointerQueueState, "%p");
+    ok(stubMsg.pPointerQueueState == 0 ||
+       broken(stubMsg.pPointerQueueState == (void *)0xcccccccc), /* win2k */
+       "stubMsg.pPointerQueueState should have been unset instead of %p\n", stubMsg.pPointerQueueState);
     TEST_ZERO(IgnoreEmbeddedPointers, "%d");
     TEST_ZERO(PointerBufferMark, "%p");
-    ok(stubMsg.fBufferValid == 0xcc, "fBufferValid should have been unset instead of 0x%x\n", stubMsg.fBufferValid);
+    ok(stubMsg.CorrDespIncrement == 0xcc ||
+       stubMsg.CorrDespIncrement == 0,
+       "CorrDespIncrement should have been unset instead of 0x%x\n", stubMsg.CorrDespIncrement);
     TEST_ZERO(uFlags, "%d");
     /* FIXME: UniquePtrCount */
     TEST_ULONG_PTR_UNSET(MaxCount);
@@ -1198,12 +1295,23 @@ todo_wine
     TEST_ZERO(PointerLength, "%d");
     TEST_ZERO(fInDontFree, "%d");
     TEST_ZERO(fDontCallFreeInst, "%d");
-    TEST_ZERO(fInOnlyParam, "%d");
+    ok(stubMsg.fInOnlyParam == 0 ||
+       stubMsg.fInOnlyParam == -1, /* Vista */
+       "fInOnlyParam should have been set to 0 or -1 instead of %d\n", stubMsg.fInOnlyParam);
     TEST_ZERO(fHasReturn, "%d");
     TEST_ZERO(fHasExtensions, "%d");
     TEST_ZERO(fHasNewCorrDesc, "%d");
-    TEST_ZERO(fUnused, "%d");
-    ok(stubMsg.fUnused2 == 0xffffcccc, "stubMsg.fUnused2 should have been 0xcccc instead of 0x%x\n", stubMsg.fUnused2);
+    TEST_ZERO(fIsIn, "%d");
+    TEST_ZERO(fIsOut, "%d");
+    TEST_ZERO(fIsOicf, "%d");
+    trace("fBufferValid = %d\n", stubMsg.fBufferValid);
+    TEST_ZERO(fHasMemoryValidateCallback, "%d");
+    TEST_ZERO(fInFree, "%d");
+    TEST_ZERO(fNeedMCCP, "%d");
+    ok(stubMsg.fUnused == 0 ||
+       stubMsg.fUnused == -2, /* Vista */
+       "fUnused should have been set to 0 or -2 instead of %d\n", stubMsg.fUnused);
+    ok(stubMsg.fUnused2 == 0xffffcccc, "stubMsg.fUnused2 should have been 0xffffcccc instead of 0x%x\n", stubMsg.fUnused2);
     ok(stubMsg.dwDestContext == MSHCTX_DIFFERENTMACHINE, "stubMsg.dwDestContext should have been MSHCTX_DIFFERENTMACHINE instead of %d\n", stubMsg.dwDestContext);
     TEST_ZERO(pvDestContext, "%p");
     TEST_POINTER_UNSET(SavedContextHandles);
@@ -1315,6 +1423,7 @@ static void test_conformant_array(void)
     void *ptr;
     unsigned char *mem, *mem_orig;
     unsigned char memsrc[20];
+    unsigned int i;
 
     static const unsigned char fmtstr_conf_array[] =
     {
@@ -1328,6 +1437,9 @@ static void test_conformant_array(void)
         0x5b               /* FC_END */
     };
 
+    for (i = 0; i < sizeof(memsrc); i++)
+        memsrc[i] = i * i;
+
     StubDesc = Object_StubDesc;
     StubDesc.pFormatTypes = fmtstr_conf_array;
 
@@ -1705,6 +1817,105 @@ static void test_nonconformant_string(void)
     HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
 }
 
+static void test_conf_complex_struct(void)
+{
+    RPC_MESSAGE RpcMessage;
+    MIDL_STUB_MESSAGE StubMsg;
+    MIDL_STUB_DESC StubDesc;
+    void *ptr;
+    unsigned int i;
+    struct conf_complex
+    {
+      unsigned int size;
+      unsigned int *array[1];
+    };
+    struct conf_complex *memsrc;
+    struct conf_complex *mem;
+
+    static const unsigned char fmtstr_complex_struct[] =
+    {
+/* 0 */
+                       0x1b,           /* FC_CARRAY */
+                       0x3,            /* 3 */
+/* 2 */        NdrFcShort( 0x4 ),      /* 4 */
+/* 4 */        0x8,            /* Corr desc: FC_LONG */
+                       0x0,            /*  */
+/* 6 */        NdrFcShort( 0xfffc ),   /* -4 */
+/* 8 */
+                       0x4b,           /* FC_PP */
+                       0x5c,           /* FC_PAD */
+/* 10 */
+                       0x48,           /* FC_VARIABLE_REPEAT */
+                       0x49,           /* FC_FIXED_OFFSET */
+/* 12 */       NdrFcShort( 0x4 ),      /* 4 */
+/* 14 */       NdrFcShort( 0x0 ),      /* 0 */
+/* 16 */       NdrFcShort( 0x1 ),      /* 1 */
+/* 18 */       NdrFcShort( 0x0 ),      /* 0 */
+/* 20 */       NdrFcShort( 0x0 ),      /* 0 */
+/* 22 */       0x12, 0x8,      /* FC_UP [simple_pointer] */
+/* 24 */       0x8,            /* FC_LONG */
+                       0x5c,           /* FC_PAD */
+/* 26 */
+                       0x5b,           /* FC_END */
+
+                       0x8,            /* FC_LONG */
+/* 28 */       0x5c,           /* FC_PAD */
+                       0x5b,           /* FC_END */
+/* 30 */
+                       0x1a,           /* FC_BOGUS_STRUCT */
+                       0x3,            /* 3 */
+/* 32 */       NdrFcShort( 0x4 ),      /* 4 */
+/* 34 */       NdrFcShort( 0xffffffde ),       /* Offset= -34 (0) */
+/* 36 */       NdrFcShort( 0x0 ),      /* Offset= 0 (36) */
+/* 38 */       0x8,            /* FC_LONG */
+                       0x5b,           /* FC_END */
+    };
+
+    memsrc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                       FIELD_OFFSET(struct conf_complex, array[20]));
+    memsrc->size = 20;
+
+    StubDesc = Object_StubDesc;
+    StubDesc.pFormatTypes = fmtstr_complex_struct;
+
+    NdrClientInitializeNew(
+                           &RpcMessage,
+                           &StubMsg,
+                           &StubDesc,
+                           0);
+
+    StubMsg.BufferLength = 0;
+    NdrComplexStructBufferSize( &StubMsg,
+                                (unsigned char *)memsrc,
+                                &fmtstr_complex_struct[30] );
+    ok(StubMsg.BufferLength >= 28, "length %d\n", StubMsg.BufferLength);
+
+    /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/
+    StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength);
+    StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength;
+
+    ptr = NdrComplexStructMarshall( &StubMsg, (unsigned char *)memsrc,
+                                    &fmtstr_complex_struct[30] );
+    ok(ptr == NULL, "ret %p\n", ptr);
+    ok(*(unsigned int *)StubMsg.BufferStart == 20, "Conformance should have been 20 instead of %d\n", (unsigned int)StubMsg.BufferStart);
+    ok(*(unsigned int *)(StubMsg.BufferStart + 4) == 20, "conf_complex.size should have been 20 instead of %d\n", (unsigned int)(StubMsg.BufferStart + 4));
+    for (i = 0; i < 20; i++)
+      ok(*(unsigned int *)(StubMsg.BufferStart + 8 + i * 4) == 0, "pointer id for conf_complex.array[%d] should have been 0 instead of 0x%x\n", i, *(unsigned int *)(StubMsg.BufferStart + 8 + i * 4));
+
+    /* Server */
+    my_alloc_called = 0;
+    StubMsg.IsClient = 0;
+    mem = NULL;
+    StubMsg.Buffer = StubMsg.BufferStart;
+    ptr = NdrComplexStructUnmarshall( &StubMsg, (unsigned char **)&mem, &fmtstr_complex_struct[30], 0);
+    ok(ptr == NULL, "ret %p\n", ptr);
+    ok(mem->size == 20, "mem->size wasn't unmarshalled correctly (%d)\n", mem->size);
+    ok(mem->array[0] == NULL, "mem->array[0] wasn't unmarshalled correctly (%p)\n", mem->array[0]);
+    StubMsg.pfnFree(mem);
+
+    HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer);
+}
+
 static void test_ndr_buffer(void)
 {
     static unsigned char ncalrpc[] = "ncalrpc";
@@ -1716,6 +1927,8 @@ static void test_ndr_buffer(void)
     unsigned char *binding;
     RPC_BINDING_HANDLE Handle;
     RPC_STATUS status;
+    ULONG prev_buffer_length;
+    BOOL old_buffer_valid_location;
 
     StubDesc.RpcInterfaceInformation = (void *)&IFoo___RpcServerInterface;
 
@@ -1744,23 +1957,33 @@ static void test_ndr_buffer(void)
     ok(ret == StubMsg.Buffer, "NdrGetBuffer should have returned the same value as StubMsg.Buffer instead of %p\n", ret);
     ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
     ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
-    ok(RpcMessage.BufferLength == 10, "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage.BufferLength);
+    ok(RpcMessage.BufferLength == 10 ||
+       broken(RpcMessage.BufferLength == 12), /* win2k */
+       "RpcMessage.BufferLength should have been 10 instead of %d\n", RpcMessage.BufferLength);
     ok(RpcMessage.RpcFlags == 0, "RpcMessage.RpcFlags should have been 0x0 instead of 0x%lx\n", RpcMessage.RpcFlags);
     ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
     ok(!StubMsg.BufferStart, "BufferStart should have been NULL instead of %p\n", StubMsg.BufferStart);
     ok(!StubMsg.BufferEnd, "BufferEnd should have been NULL instead of %p\n", StubMsg.BufferEnd);
 todo_wine
     ok(StubMsg.BufferLength == 0, "BufferLength should have left as 0 instead of being set to %d\n", StubMsg.BufferLength);
-    ok(StubMsg.fBufferValid == TRUE, "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg.fBufferValid);
+    old_buffer_valid_location = !StubMsg.fBufferValid;
+    if (old_buffer_valid_location)
+        ok(broken(StubMsg.CorrDespIncrement == TRUE), "fBufferValid should have been TRUE instead of 0x%x\n", StubMsg.CorrDespIncrement);
+    else
+        ok(StubMsg.fBufferValid, "fBufferValid should have been non-zero instead of 0x%x\n", StubMsg.fBufferValid);
 
+    prev_buffer_length = RpcMessage.BufferLength;
     StubMsg.BufferLength = 1;
     NdrFreeBuffer(&StubMsg);
     ok(RpcMessage.Handle != NULL, "RpcMessage.Handle should not have been NULL\n");
     ok(RpcMessage.Buffer != NULL, "RpcMessage.Buffer should not have been NULL\n");
-    ok(RpcMessage.BufferLength == 10, "RpcMessage.BufferLength should have been left as 10 instead of %d\n", RpcMessage.BufferLength);
+    ok(RpcMessage.BufferLength == prev_buffer_length, "RpcMessage.BufferLength should have been left as %d instead of %d\n", prev_buffer_length, RpcMessage.BufferLength);
     ok(StubMsg.Buffer != NULL, "Buffer should not have been NULL\n");
     ok(StubMsg.BufferLength == 1, "BufferLength should have left as 1 instead of being set to %d\n", StubMsg.BufferLength);
-    ok(StubMsg.fBufferValid == FALSE, "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg.fBufferValid);
+    if (old_buffer_valid_location)
+        ok(broken(StubMsg.CorrDespIncrement == FALSE), "fBufferValid should have been FALSE instead of 0x%x\n", StubMsg.CorrDespIncrement);
+    else
+        ok(!StubMsg.fBufferValid, "fBufferValid should have been FALSE instead of %d\n", StubMsg.fBufferValid);
 
     /* attempt double-free */
     NdrFreeBuffer(&StubMsg);
@@ -1816,6 +2039,8 @@ static void test_NdrMapCommAndFaultStatus(void)
 
 START_TEST( ndr_marshall )
 {
+    determine_pointer_marshalling_style();
+
     test_ndr_simple_type();
     test_simple_types();
     test_nontrivial_pointer_types();
@@ -1827,6 +2052,7 @@ START_TEST( ndr_marshall )
     test_conformant_array();
     test_conformant_string();
     test_nonconformant_string();
+    test_conf_complex_struct();
     test_ndr_buffer();
     test_NdrMapCommAndFaultStatus();
 }
index 4197707..d59b5ba 100644 (file)
@@ -261,6 +261,10 @@ todo_wine {
     ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%lu)\n",
        status);
 
+    status = RpcBindingSetAuthInfo(IFoo_IfHandle, NULL, RPC_C_AUTHN_LEVEL_NONE,
+                                   RPC_C_AUTHN_WINNT, NULL, RPC_C_AUTHZ_NAME);
+    ok(status == RPC_S_OK, "RpcBindingSetAuthInfo failed (%lu)\n", status);
+
     status = RpcMgmtStopServerListening(NULL);
     ok(status == RPC_S_OK, "RpcMgmtStopServerListening failed (%lu)\n",
        status);
@@ -325,7 +329,9 @@ static void test_towers(void)
     BOOL same;
 
     ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_ip_tcp", "135", "10.0.0.1", &tower);
-    ok(ret == RPC_S_OK, "TowerConstruct failed with error %ld\n", ret);
+    ok(ret == RPC_S_OK ||
+       broken(ret == RPC_S_INVALID_RPC_PROTSEQ), /* Vista */
+       "TowerConstruct failed with error %ld\n", ret);
     if (ret == RPC_S_INVALID_RPC_PROTSEQ)
     {
         /* Windows Vista fails with this error and crashes if we continue */
@@ -388,7 +394,9 @@ static void test_towers(void)
     ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_np", "\\pipe\\test", NULL, &tower);
     ok(ret == RPC_S_OK, "TowerConstruct failed with error %ld\n", ret);
     ret = TowerExplode(tower, NULL, NULL, NULL, NULL, &address);
-    ok(ret == RPC_S_OK, "TowerExplode failed with error %ld\n", ret);
+    ok(ret == RPC_S_OK ||
+       broken(ret != RPC_S_OK), /* win2k, indeterminate */
+       "TowerExplode failed with error %ld\n", ret);
     /* Windows XP SP3 sets address to NULL */
     ok(!address || !strcmp(address, ""), "address was \"%s\" instead of \"\"\n or NULL (XP SP3)", address);
 
@@ -400,8 +408,14 @@ static void test_I_RpcMapWin32Status(void)
 {
     LONG win32status;
     RPC_STATUS rpc_status;
+    BOOL on_win9x = FALSE;
     BOOL w2k3_up = FALSE;
 
+    /* Win9x always returns the given status */
+    win32status = I_RpcMapWin32Status(ERROR_ACCESS_DENIED);
+    if (win32status == ERROR_ACCESS_DENIED)
+        on_win9x = TRUE;
+
     /* Windows 2003 and Vista return STATUS_UNSUCCESSFUL if given an unknown status */
     win32status = I_RpcMapWin32Status(9999);
     if (win32status == STATUS_UNSUCCESSFUL)
@@ -410,9 +424,14 @@ static void test_I_RpcMapWin32Status(void)
         w2k3_up = TRUE;
     }
 
+    /* On Windows XP-SP1 and below some statuses are not mapped and return
+     * the given status
+     */
     for (rpc_status = 0; rpc_status < 10000; rpc_status++)
     {
         LONG expected_win32status;
+        BOOL missing = FALSE;
+
         win32status = I_RpcMapWin32Status(rpc_status);
         switch (rpc_status)
         {
@@ -425,10 +444,10 @@ static void test_I_RpcMapWin32Status(void)
         case ERROR_MAX_THRDS_REACHED: expected_win32status = STATUS_NO_MEMORY; break;
         case ERROR_NOACCESS: expected_win32status = STATUS_ACCESS_VIOLATION; break;
         case ERROR_NOT_ENOUGH_SERVER_MEMORY: expected_win32status = STATUS_INSUFF_SERVER_RESOURCES; break;
-        case ERROR_WRONG_PASSWORD: expected_win32status = STATUS_WRONG_PASSWORD; break;
-        case ERROR_INVALID_LOGON_HOURS: expected_win32status = STATUS_INVALID_LOGON_HOURS; break;
-        case ERROR_PASSWORD_EXPIRED: expected_win32status = STATUS_PASSWORD_EXPIRED; break;
-        case ERROR_ACCOUNT_DISABLED: expected_win32status = STATUS_ACCOUNT_DISABLED; break;
+        case ERROR_WRONG_PASSWORD:  expected_win32status = STATUS_WRONG_PASSWORD; missing = TRUE; break;
+        case ERROR_INVALID_LOGON_HOURS: expected_win32status = STATUS_INVALID_LOGON_HOURS; missing = TRUE; break;
+        case ERROR_PASSWORD_EXPIRED: expected_win32status = STATUS_PASSWORD_EXPIRED; missing = TRUE; break;
+        case ERROR_ACCOUNT_DISABLED: expected_win32status = STATUS_ACCOUNT_DISABLED; missing = TRUE; break;
         case ERROR_INVALID_SECURITY_DESCR: expected_win32status = STATUS_INVALID_SECURITY_DESCR; break;
         case RPC_S_INVALID_STRING_BINDING: expected_win32status = RPC_NT_INVALID_STRING_BINDING; break;
         case RPC_S_WRONG_KIND_OF_BINDING: expected_win32status = RPC_NT_WRONG_KIND_OF_BINDING; break;
@@ -502,10 +521,10 @@ static void test_I_RpcMapWin32Status(void)
         case RPC_S_FP_OVERFLOW: expected_win32status = RPC_NT_FP_OVERFLOW; break;
         case RPC_S_CALL_IN_PROGRESS: expected_win32status = RPC_NT_CALL_IN_PROGRESS; break;
         case RPC_S_NO_MORE_BINDINGS: expected_win32status = RPC_NT_NO_MORE_BINDINGS; break;
-        case RPC_S_CALL_CANCELLED: expected_win32status = RPC_NT_CALL_CANCELLED; break;
+        case RPC_S_CALL_CANCELLED: expected_win32status = RPC_NT_CALL_CANCELLED; missing = TRUE; break;
         case RPC_S_INVALID_OBJECT: expected_win32status = RPC_NT_INVALID_OBJECT; break;
-        case RPC_S_INVALID_ASYNC_HANDLE: expected_win32status = RPC_NT_INVALID_ASYNC_HANDLE; break;
-        case RPC_S_INVALID_ASYNC_CALL: expected_win32status = RPC_NT_INVALID_ASYNC_CALL; break;
+        case RPC_S_INVALID_ASYNC_HANDLE: expected_win32status = RPC_NT_INVALID_ASYNC_HANDLE; missing = TRUE; break;
+        case RPC_S_INVALID_ASYNC_CALL: expected_win32status = RPC_NT_INVALID_ASYNC_CALL; missing = TRUE; break;
         case RPC_S_GROUP_MEMBER_NOT_FOUND: expected_win32status = RPC_NT_GROUP_MEMBER_NOT_FOUND; break;
         case RPC_X_NO_MORE_ENTRIES: expected_win32status = RPC_NT_NO_MORE_ENTRIES; break;
         case RPC_X_SS_CHAR_TRANS_OPEN_FAIL: expected_win32status = RPC_NT_SS_CHAR_TRANS_OPEN_FAIL; break;
@@ -518,19 +537,26 @@ static void test_I_RpcMapWin32Status(void)
         case RPC_X_ENUM_VALUE_OUT_OF_RANGE: expected_win32status = RPC_NT_ENUM_VALUE_OUT_OF_RANGE; break;
         case RPC_X_BYTE_COUNT_TOO_SMALL: expected_win32status = RPC_NT_BYTE_COUNT_TOO_SMALL; break;
         case RPC_X_BAD_STUB_DATA: expected_win32status = RPC_NT_BAD_STUB_DATA; break;
-        case RPC_X_PIPE_CLOSED: expected_win32status = RPC_NT_PIPE_CLOSED; break;
-        case RPC_X_PIPE_DISCIPLINE_ERROR: expected_win32status = RPC_NT_PIPE_DISCIPLINE_ERROR; break;
-        case RPC_X_PIPE_EMPTY: expected_win32status = RPC_NT_PIPE_EMPTY; break;
-        case ERROR_PASSWORD_MUST_CHANGE: expected_win32status = STATUS_PASSWORD_MUST_CHANGE; break;
-        case ERROR_ACCOUNT_LOCKED_OUT: expected_win32status = STATUS_ACCOUNT_LOCKED_OUT; break;
+        case RPC_X_PIPE_CLOSED: expected_win32status = RPC_NT_PIPE_CLOSED; missing = TRUE; break;
+        case RPC_X_PIPE_DISCIPLINE_ERROR: expected_win32status = RPC_NT_PIPE_DISCIPLINE_ERROR; missing = TRUE; break;
+        case RPC_X_PIPE_EMPTY: expected_win32status = RPC_NT_PIPE_EMPTY; missing = TRUE; break;
+        case ERROR_PASSWORD_MUST_CHANGE: expected_win32status = STATUS_PASSWORD_MUST_CHANGE; missing = TRUE; break;
+        case ERROR_ACCOUNT_LOCKED_OUT: expected_win32status = STATUS_ACCOUNT_LOCKED_OUT; missing = TRUE; break;
         default:
             if (w2k3_up)
                 expected_win32status = STATUS_UNSUCCESSFUL;
             else
                 expected_win32status = rpc_status;
         }
-        ok(win32status == expected_win32status, "I_RpcMapWin32Status(%ld) should have returned 0x%x instead of 0x%x\n",
-            rpc_status, expected_win32status, win32status);
+
+        if (on_win9x)
+            missing = TRUE;
+
+        ok(win32status == expected_win32status ||
+            broken(missing && win32status == rpc_status),
+            "I_RpcMapWin32Status(%ld) should have returned 0x%x instead of 0x%x%s\n",
+            rpc_status, expected_win32status, win32status,
+            broken(missing) ? " (or have returned with the given status)" : "");
     }
 }
 
@@ -554,7 +580,6 @@ static void test_RpcStringBindingParseA(void)
     ok(!strcmp((char *)uuid, "00000000-0000-0000-c000-000000000046"), "uuid should have been 00000000-0000-0000-C000-000000000046 instead of %s\n", uuid);
     ok(!strcmp((char *)protseq, "ncacn_np"), "protseq should have been ncacn_np instead of %s\n", protseq);
     ok(!strcmp((char *)network_addr, "."), "network_addr should have been . instead of %s\n", network_addr);
-    todo_wine
     ok(!strcmp((char *)endpoint, "pipetest"), "endpoint should have been pipetest instead of %s\n", endpoint);
     todo_wine
     ok(options && !strcmp((char *)options, ""), "options should have been \"\" of \"%s\"\n", options);
@@ -570,7 +595,6 @@ static void test_RpcStringBindingParseA(void)
     ok(!strcmp((char *)uuid, "00000000-0000-0000-c000-000000000046"), "uuid should have been 00000000-0000-0000-C000-000000000046 instead of %s\n", uuid);
     ok(!strcmp((char *)protseq, "ncacn_np"), "protseq should have been ncacn_np instead of %s\n", protseq);
     ok(!strcmp((char *)network_addr, "."), "network_addr should have been . instead of %s\n", network_addr);
-    todo_wine
     ok(!strcmp((char *)endpoint, "pipetest"), "endpoint should have been pipetest instead of %s\n", endpoint);
     todo_wine
     ok(options && !strcmp((char *)options, ""), "options should have been \"\" of \"%s\"\n", options);
@@ -588,9 +612,7 @@ static void test_RpcStringBindingParseA(void)
 
     /* test with invalid uuid */
     status = RpcStringBindingParseA(invalid_uuid_binding, NULL, &protseq, NULL, NULL, NULL);
-    todo_wine
     ok(status == RPC_S_INVALID_STRING_UUID, "RpcStringBindingParseA should have returned RPC_S_INVALID_STRING_UUID instead of %ld\n", status);
-    todo_wine
     ok(protseq == NULL, "protseq was %p instead of NULL\n", protseq);
 
     /* test with invalid endpoint */
@@ -644,6 +666,10 @@ static void test_I_RpcExceptionFilter(void)
             ok(retval == EXCEPTION_CONTINUE_SEARCH, "I_RpcExceptionFilter(0x%x) should have returned %d instead of %d\n",
                exception, EXCEPTION_CONTINUE_SEARCH, retval);
             break;
+        case STATUS_IN_PAGE_ERROR:
+        case STATUS_HANDLE_NOT_CLOSABLE:
+            trace("I_RpcExceptionFilter(0x%x) returned %d\n", exception, retval);
+            break;
         default:
             ok(retval == EXCEPTION_EXECUTE_HANDLER, "I_RpcExceptionFilter(0x%x) should have returned %d instead of %d\n",
                exception, EXCEPTION_EXECUTE_HANDLER, retval);
@@ -651,15 +677,104 @@ static void test_I_RpcExceptionFilter(void)
     }
 }
 
+static void test_endpoint_mapper(RPC_CSTR protseq, RPC_CSTR address,
+                                 RPC_CSTR endpoint)
+{
+    static unsigned char annotation[] = "Test annotation string.";
+    RPC_STATUS status;
+    RPC_BINDING_VECTOR *binding_vector;
+    handle_t handle;
+    unsigned char *binding;
+
+    status = RpcServerUseProtseqEp(protseq, 20, endpoint, NULL);
+    ok(status == RPC_S_OK, "%s: RpcServerUseProtseqEp failed (%lu)\n", protseq, status);
+
+    status = RpcServerRegisterIf(IFoo_v0_0_s_ifspec, NULL, NULL);
+    ok(status == RPC_S_OK, "%s: RpcServerRegisterIf failed (%lu)\n", protseq, status);
+
+    status = RpcServerInqBindings(&binding_vector);
+    ok(status == RPC_S_OK, "%s: RpcServerInqBindings failed with error %lu\n", protseq, status);
+
+    status = RpcEpRegisterA(IFoo_v0_0_s_ifspec, binding_vector, NULL, annotation);
+    ok(status == RPC_S_OK, "%s: RpcEpRegisterA failed with error %lu\n", protseq, status);
+
+    status = RpcStringBindingCompose(NULL, protseq, address,
+                                     NULL, NULL, &binding);
+    ok(status == RPC_S_OK, "%s: RpcStringBindingCompose failed (%lu)\n", protseq, status);
+
+    status = RpcBindingFromStringBinding(binding, &handle);
+    ok(status == RPC_S_OK, "%s: RpcBindingFromStringBinding failed (%lu)\n", protseq, status);
+
+    RpcStringFree(&binding);
+
+    status = RpcBindingReset(handle);
+    ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %lu\n", protseq, status);
+
+    RpcStringFree(&binding);
+
+    status = RpcEpResolveBinding(handle, IFoo_v0_0_s_ifspec);
+    ok(status == RPC_S_OK, "%s: RpcEpResolveBinding failed with error %lu\n", protseq, status);
+
+    status = RpcBindingReset(handle);
+    ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %lu\n", protseq, status);
+
+    status = RpcBindingFree(&handle);
+    ok(status == RPC_S_OK, "%s: RpcBindingFree failed with error %lu\n", protseq, status);
+
+    status = RpcServerUnregisterIf(NULL, NULL, FALSE);
+    ok(status == RPC_S_OK, "%s: RpcServerUnregisterIf failed (%lu)\n", protseq, status);
+
+    status = RpcEpUnregister(IFoo_v0_0_s_ifspec, binding_vector, NULL);
+    ok(status == RPC_S_OK, "%s: RpcEpUnregisterA failed with error %lu\n", protseq, status);
+
+    status = RpcBindingVectorFree(&binding_vector);
+    ok(status == RPC_S_OK, "%s: RpcBindingVectorFree failed with error %lu\n", protseq, status);
+}
+
+static void test_RpcStringBindingFromBinding(void)
+{
+    static unsigned char ncacn_np[] = "ncacn_np";
+    static unsigned char address[] = ".";
+    static unsigned char endpoint[] = "\\pipe\\wine_rpc_test";
+    RPC_STATUS status;
+    handle_t handle;
+    RPC_CSTR binding;
+
+    status = RpcStringBindingCompose(NULL, ncacn_np, address,
+                                     endpoint, NULL, &binding);
+    ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%lu)\n", status);
+
+    status = RpcBindingFromStringBinding(binding, &handle);
+    ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%lu)\n", status);
+    RpcStringFree(&binding);
+
+    status = RpcBindingToStringBinding(handle, &binding);
+    ok(status == RPC_S_OK, "RpcStringBindingFromBinding failed with error %lu\n", status);
+
+    ok(!strcmp((const char *)binding, "ncacn_np:.[\\\\pipe\\\\wine_rpc_test]"),
+       "binding string didn't match what was expected: \"%s\"\n", binding);
+    RpcStringFree(&binding);
+
+    status = RpcBindingFree(&handle);
+    ok(status == RPC_S_OK, "RpcBindingFree failed with error %lu\n", status);
+}
+
 START_TEST( rpc )
 {
-    trace ( " ** Uuid Conversion and Comparison Tests **\n" );
+    static unsigned char ncacn_np[] = "ncacn_np";
+    static unsigned char ncalrpc[] = "ncalrpc";
+    static unsigned char np_address[] = ".";
+    static unsigned char np_endpoint[] = "\\pipe\\wine_rpc_test";
+    static unsigned char lrpc_endpoint[] = "wine_rpc_test";
+
     UuidConversionAndComparison();
-    trace ( " ** DceErrorInqText **\n");
     TestDceErrorInqText();
     test_rpc_ncacn_ip_tcp();
     test_towers();
     test_I_RpcMapWin32Status();
     test_RpcStringBindingParseA();
     test_I_RpcExceptionFilter();
+    test_endpoint_mapper(ncacn_np, np_address, np_endpoint);
+    test_endpoint_mapper(ncalrpc, NULL, lrpc_endpoint);
+    test_RpcStringBindingFromBinding();
 }
index eb1baac..a28f1c6 100644 (file)
@@ -333,12 +333,30 @@ s_square_encu(encu_t *eu)
   }
 }
 
+double
+s_square_unencu(int t, unencu_t *eu)
+{
+  switch (t)
+  {
+  case ENCU_I: return eu->i * eu->i;
+  case ENCU_F: return eu->f * eu->f;
+  default:
+    return 0.0;
+  }
+}
+
 void
 s_check_se2(se_t *s)
 {
   ok(s->f == E2, "check_se2\n");
 }
 
+int
+s_sum_parr(int *a[3])
+{
+  return s_sum_pcarr(a, 3);
+}
+
 int
 s_sum_pcarr(int *a[], int n)
 {
@@ -348,12 +366,6 @@ s_sum_pcarr(int *a[], int n)
   return s;
 }
 
-int
-s_sum_parr(int *a[3])
-{
-  return s_sum_pcarr(a, 3);
-}
-
 int
 s_enum_ord(e_t e)
 {
@@ -653,6 +665,24 @@ s_get_numbers(int length, int size, pints_t n[])
     }
 }
 
+void
+s_get_numbers_struct(numbers_struct_t **ns)
+{
+    int i;
+    *ns = midl_user_allocate(FIELD_OFFSET(numbers_struct_t, numbers[5]));
+    if (!*ns) return;
+    (*ns)->length = 5;
+    (*ns)->size = 5;
+    for (i = 0; i < (*ns)->length; i++)
+    {
+        (*ns)->numbers[i].pi = NULL;
+        (*ns)->numbers[i].ppi = NULL;
+        (*ns)->numbers[i].pppi = NULL;
+    }
+    (*ns)->numbers[0].pi = midl_user_allocate(sizeof(*(*ns)->numbers[i].pi));
+    *(*ns)->numbers[0].pi = 5;
+}
+
 void
 s_stop(void)
 {
@@ -826,6 +856,7 @@ union_tests(void)
 {
   encue_t eue;
   encu_t eu;
+  unencu_t uneu;
   sun_t su;
   int i;
 
@@ -854,6 +885,12 @@ union_tests(void)
   eu.tagged_union.f = 3.0;
   ok(square_encu(&eu) == 9.0, "RPC square_encu\n");
 
+  uneu.i = 4;
+  ok(square_unencu(ENCU_I, &uneu) == 16.0, "RPC square_unencu\n");
+
+  uneu.f = 5.0;
+  ok(square_unencu(ENCU_F, &uneu) == 25.0, "RPC square_unencu\n");
+
   eue.t = E1;
   eue.tagged_union.i1 = 8;
   ok(square_encue(&eue) == 64.0, "RPC square_encue\n");
@@ -1096,6 +1133,7 @@ array_tests(void)
   doub_carr_t *dc;
   int *pi;
   pints_t api[5];
+  numbers_struct_t *ns;
 
   ok(cstr_length(str1, sizeof str1) == strlen(str1), "RPC cstr_length\n");
 
@@ -1177,12 +1215,22 @@ array_tests(void)
   api[0].pi = pi;
   get_5numbers(1, api);
   ok(api[0].pi == pi, "RPC varying array [out] pointer changed from %p to %p\n", pi, api[0].pi);
-  ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *pi);
+  ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *api[0].pi);
 
   api[0].pi = pi;
   get_numbers(1, 1, api);
   ok(api[0].pi == pi, "RPC conformant varying array [out] pointer changed from %p to %p\n", pi, api[0].pi);
-  ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *pi);
+  ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *api[0].pi);
+
+  ns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(numbers_struct_t, numbers[5]));
+  ns->length = 5;
+  ns->size = 5;
+  ns->numbers[0].pi = pi;
+  get_numbers_struct(&ns);
+  ok(ns->numbers[0].pi == pi, "RPC conformant varying struct embedded pointer changed from %p to %p\n", pi, ns->numbers[0].pi);
+  ok(*ns->numbers[0].pi == 5, "pi unmarshalled incorrectly %d\n", *ns->numbers[0].pi);
+
+  HeapFree(GetProcessHeap(), 0, ns);
   HeapFree(GetProcessHeap(), 0, pi);
 }
 
@@ -1240,14 +1288,29 @@ server(void)
   static unsigned char np[] = "ncacn_np";
   static unsigned char pipe[] = PIPE;
   RPC_STATUS status, iptcp_status, np_status;
+  RPC_STATUS (RPC_ENTRY *pRpcServerRegisterIfEx)(RPC_IF_HANDLE,UUID*,
+    RPC_MGR_EPV*, unsigned int,unsigned int,RPC_IF_CALLBACK_FN*);
+  DWORD ret;
 
   iptcp_status = RpcServerUseProtseqEp(iptcp, 20, port, NULL);
   ok(iptcp_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_ip_tcp) failed with status %ld\n", iptcp_status);
   np_status = RpcServerUseProtseqEp(np, 0, pipe, NULL);
-  ok(np_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %ld\n", np_status);
+  if (np_status == RPC_S_PROTSEQ_NOT_SUPPORTED)
+    skip("Protocol sequence ncacn_np is not supported\n");
+  else
+    ok(np_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %ld\n", np_status);
 
-  //status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL);
-  //ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %ld\n", status);
+  pRpcServerRegisterIfEx = (void *)GetProcAddress(GetModuleHandle("rpcrt4.dll"), "RpcServerRegisterIfEx");
+  if (pRpcServerRegisterIfEx)
+  {
+    trace("Using RpcServerRegisterIfEx\n");
+    status = pRpcServerRegisterIfEx(IServer_v0_0_s_ifspec, NULL, NULL,
+                                    RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH,
+                                    RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
+  }
+  else
+    status = RpcServerRegisterIf(IServer_v0_0_s_ifspec, NULL, NULL);
+  ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %ld\n", status);
   status = RpcServerListen(1, 20, TRUE);
   ok(status == RPC_S_OK, "RpcServerListen failed with status %ld\n", status);
   stop_event = CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -1267,10 +1330,16 @@ server(void)
     return;
   }
 
-  ok(WAIT_OBJECT_0 == WaitForSingleObject(stop_event, 60000), "WaitForSingleObject\n");
-  status = RpcMgmtWaitServerListen();
-  todo_wine {
-    ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %ld\n", status);
+  ret = WaitForSingleObject(stop_event, 1000);
+  ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
+  /* if the stop event didn't fire then RpcMgmtWaitServerListen will wait
+   * forever, so don't bother calling it in this case */
+  if (ret == WAIT_OBJECT_0)
+  {
+    status = RpcMgmtWaitServerListen();
+    todo_wine {
+      ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %ld\n", status);
+    }
   }
 }
 
index 33e3a48..26d3373 100644 (file)
@@ -195,6 +195,12 @@ cpp_quote("#endif")
   case ENCU_F: float f;
   } encu_t;
 
+  typedef [switch_type(int)] union unencu
+  {
+    [case (ENCU_I)] int i;
+    [case (ENCU_F)] float f;
+  } unencu_t;
+
   typedef enum
   {
     E1 = 23,
@@ -215,6 +221,7 @@ cpp_quote("#endif")
   } se_t;
 
   double square_encu(encu_t *eu);
+  double square_unencu(int t, [switch_is(t)] unencu_t *eu);
   int sum_parr(int *a[3]);
   int sum_pcarr([size_is(n)] int *a[], int n);
   int enum_ord(e_t e);
@@ -319,8 +326,17 @@ cpp_quote("#endif")
      type as a return value.  */
   s123_t *get_s123(void);
 
+  typedef struct
+  {
+    unsigned int length;
+    unsigned int size;
+    [size_is(size), length_is(length)] pints_t numbers[];
+  } numbers_struct_t;
+
   void get_5numbers([in] int count, [out, length_is(count)] pints_t pn[5]);
   void get_numbers([in] int length, [in] int size, [out, length_is(length), size_is(size)] pints_t pn[]);
+  void get_numbers_struct([out] numbers_struct_t **ns);
+
   str_t get_filename(void);
   void context_handle_test(void);
   void stop(void);