1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Unit test suite for rpc functions
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2002 Greg Turner
5c2c66affSColin Finck  * Copyright 2008-2009 Robert Shearman
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck #include <stdarg.h>
23c2c66affSColin Finck #include <stdio.h>
24c2c66affSColin Finck 
25c2c66affSColin Finck #define COBJMACROS
26c2c66affSColin Finck #include <ntstatus.h>
27c2c66affSColin Finck #define WIN32_NO_STATUS
28c2c66affSColin Finck #include "wine/test.h"
29c2c66affSColin Finck #include <windef.h>
30c2c66affSColin Finck #include <winbase.h>
31c2c66affSColin Finck #include <winnt.h>
32c2c66affSColin Finck #include <winerror.h>
33c2c66affSColin Finck #include <ole2.h>
34c2c66affSColin Finck #include <oleauto.h>
35c2c66affSColin Finck #include <ntsecapi.h>
36c2c66affSColin Finck #include <initguid.h>
37c2c66affSColin Finck #include <netfw.h>
38c2c66affSColin Finck 
39c2c66affSColin Finck #include "rpc.h"
40c2c66affSColin Finck #include "rpcdce.h"
41c2c66affSColin Finck #include "secext.h"
42c2c66affSColin Finck 
43c2c66affSColin Finck typedef unsigned int unsigned32;
44c2c66affSColin Finck typedef struct twr_t
45c2c66affSColin Finck     {
46c2c66affSColin Finck     unsigned32 tower_length;
47c2c66affSColin Finck     /* [size_is] */ byte tower_octet_string[ 1 ];
48c2c66affSColin Finck     } 	twr_t;
49c2c66affSColin Finck 
50c2c66affSColin Finck RPC_STATUS WINAPI TowerExplode(const twr_t *tower, RPC_SYNTAX_IDENTIFIER *object, RPC_SYNTAX_IDENTIFIER *syntax, char **protseq, char **endpoint, char **address);
51c2c66affSColin Finck RPC_STATUS WINAPI TowerConstruct(const RPC_SYNTAX_IDENTIFIER *object, const RPC_SYNTAX_IDENTIFIER *syntax, const char *protseq, const char *endpoint, const char *address, twr_t **tower);
52c2c66affSColin Finck 
53c2c66affSColin Finck static UUID Uuid_Table[10] = {
54c2c66affSColin Finck   { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, /* 0 (null) */
55c2c66affSColin Finck   { 0xdeadbeef, 0xdead, 0xbeef, {0x10, 0x21, 0x35, 0x56, 0x89, 0xa0, 0xf4, 0x8a} }, /* 1 */
56c2c66affSColin Finck   { 0xabadfeed, 0x49ff, 0xbead, {0x8a, 0xf4, 0xa0, 0x89, 0x56, 0x35, 0x21, 0x10} }, /* 2 */
57c2c66affSColin Finck   { 0x93da375c, 0x1324, 0x1355, {0x87, 0xff, 0x49, 0x44, 0x34, 0x44, 0x22, 0x19} }, /* 3 */
58c2c66affSColin Finck   { 0xdeadbeef, 0xdead, 0xbeef, {0x10, 0x21, 0x35, 0x56, 0x89, 0xa0, 0xf4, 0x8b} }, /* 4 (~1) */
59c2c66affSColin Finck   { 0x9badfeed, 0x49ff, 0xbead, {0x8a, 0xf4, 0xa0, 0x89, 0x56, 0x35, 0x21, 0x10} }, /* 5 (~2) */
60c2c66affSColin Finck   { 0x00000000, 0x0001, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, /* 6 (~0) */
61c2c66affSColin Finck   { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} }, /* 7 (~0) */
62c2c66affSColin Finck   { 0x12312312, 0x1231, 0x1231, {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff} }, /* 8 */
63c2c66affSColin Finck   { 0x11111111, 0x1111, 0x1111, {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11} }  /* 9 */
64c2c66affSColin Finck };
65c2c66affSColin Finck 
66c2c66affSColin Finck /* index of "10" means "NULL" */
67c2c66affSColin Finck static BOOL Uuid_Comparison_Grid[11][11] = {
68c2c66affSColin Finck   { TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE  },
69c2c66affSColin Finck   { FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
70c2c66affSColin Finck   { FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
71c2c66affSColin Finck   { FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
72c2c66affSColin Finck   { FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
73c2c66affSColin Finck   { FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE },
74c2c66affSColin Finck   { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE },
75c2c66affSColin Finck   { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE },
76c2c66affSColin Finck   { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE },
77c2c66affSColin Finck   { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE },
78c2c66affSColin Finck   { TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE  }
79c2c66affSColin Finck };
80c2c66affSColin Finck 
UuidConversionAndComparison(void)81c2c66affSColin Finck static void UuidConversionAndComparison(void) {
82c2c66affSColin Finck     CHAR strx[100], x;
83c2c66affSColin Finck     LPSTR str = strx;
84c2c66affSColin Finck     WCHAR wstrx[100], wx;
85c2c66affSColin Finck     LPWSTR wstr = wstrx;
86c2c66affSColin Finck 
87c2c66affSColin Finck     UUID Uuid1, Uuid2, *PUuid1, *PUuid2;
88c2c66affSColin Finck     RPC_STATUS rslt;
89c2c66affSColin Finck 
90c2c66affSColin Finck     int i1,i2;
91c2c66affSColin Finck 
92c2c66affSColin Finck     /* Uuid Equality */
93c2c66affSColin Finck     for (i1 = 0; i1 < 11; i1++)
94c2c66affSColin Finck         for (i2 = 0; i2 < 11; i2++) {
95c2c66affSColin Finck 	    if (i1 < 10) {
96c2c66affSColin Finck 	        Uuid1 = Uuid_Table[i1];
97c2c66affSColin Finck 		PUuid1 = &Uuid1;
98c2c66affSColin Finck             } else {
99c2c66affSColin Finck 	        PUuid1 = NULL;
100c2c66affSColin Finck 	    }
101c2c66affSColin Finck 	    if (i2 < 10) {
102c2c66affSColin Finck 	        Uuid2 = Uuid_Table[i2];
103c2c66affSColin Finck 		PUuid2 = &Uuid2;
104c2c66affSColin Finck             } else {
105c2c66affSColin Finck 	        PUuid2 = NULL;
106c2c66affSColin Finck 	    }
107c2c66affSColin Finck 	    ok( (UuidEqual(PUuid1, PUuid2, &rslt) == Uuid_Comparison_Grid[i1][i2]), "UUID Equality\n" );
108c2c66affSColin Finck         }
109c2c66affSColin Finck 
110c2c66affSColin Finck     /* Uuid to String to Uuid (char) */
111c2c66affSColin Finck     for (i1 = 0; i1 < 10; i1++) {
112c2c66affSColin Finck         Uuid1 = Uuid_Table[i1];
113c2c66affSColin Finck 	ok( (UuidToStringA(&Uuid1, (unsigned char**)&str) == RPC_S_OK), "Simple UUID->String copy\n" );
114c2c66affSColin Finck 	ok( (UuidFromStringA((unsigned char*)str, &Uuid2) == RPC_S_OK), "Simple String->UUID copy from generated UUID String\n" );
115c2c66affSColin Finck 	ok( UuidEqual(&Uuid1, &Uuid2, &rslt), "Uuid -> String -> Uuid transform\n" );
116c2c66affSColin Finck 	/* invalid uuid tests  -- size of valid UUID string=36 */
117c2c66affSColin Finck 	for (i2 = 0; i2 < 36; i2++) {
118c2c66affSColin Finck 	    x = str[i2];
119c2c66affSColin Finck 	    str[i2] = 'g'; /* whatever, but "g" is a good boundary condition */
120c2c66affSColin Finck 	    ok( (UuidFromStringA((unsigned char*)str, &Uuid1) == RPC_S_INVALID_STRING_UUID), "Invalid UUID String\n" );
121c2c66affSColin Finck 	    str[i2] = x; /* change it back so remaining tests are interesting. */
122c2c66affSColin Finck 	}
123c2c66affSColin Finck 	RpcStringFreeA((unsigned char **)&str);
124c2c66affSColin Finck     }
125c2c66affSColin Finck 
126c2c66affSColin Finck     /* Uuid to String to Uuid (wchar) */
127c2c66affSColin Finck     for (i1 = 0; i1 < 10; i1++) {
128c2c66affSColin Finck         Uuid1 = Uuid_Table[i1];
129c2c66affSColin Finck         rslt=UuidToStringW(&Uuid1, &wstr);
130c2c66affSColin Finck         ok( (rslt == RPC_S_OK), "Simple UUID->WString copy\n" );
131c2c66affSColin Finck         ok( (UuidFromStringW(wstr, &Uuid2) == RPC_S_OK), "Simple WString->UUID copy from generated UUID String\n" );
132c2c66affSColin Finck         ok( UuidEqual(&Uuid1, &Uuid2, &rslt), "Uuid -> WString -> Uuid transform\n" );
133c2c66affSColin Finck 	/* invalid uuid tests  -- size of valid UUID string=36 */
134c2c66affSColin Finck 	for (i2 = 0; i2 < 36; i2++) {
135c2c66affSColin Finck 	    wx = wstr[i2];
136c2c66affSColin Finck 	    wstr[i2] = 'g'; /* whatever, but "g" is a good boundary condition */
137c2c66affSColin Finck 	    ok( (UuidFromStringW(wstr, &Uuid1) == RPC_S_INVALID_STRING_UUID), "Invalid UUID WString\n" );
138c2c66affSColin Finck 	    wstr[i2] = wx; /* change it back so remaining tests are interesting. */
139c2c66affSColin Finck 	}
140c2c66affSColin Finck 	RpcStringFreeW(&wstr);
141c2c66affSColin Finck     }
142c2c66affSColin Finck }
143c2c66affSColin Finck 
TestDceErrorInqText(void)144c2c66affSColin Finck static void TestDceErrorInqText (void)
145c2c66affSColin Finck {
146c2c66affSColin Finck     char bufferInvalid [1024];
147c2c66affSColin Finck     char buffer [1024]; /* The required size is not documented but would
148c2c66affSColin Finck                          * appear to be 256.
149c2c66affSColin Finck                          */
150c2c66affSColin Finck     DWORD dwCount;
151c2c66affSColin Finck 
152f2f9161aSAmine Khaldi     dwCount = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
153f2f9161aSAmine Khaldi             RPC_S_NOT_RPC_ERROR, 0, bufferInvalid, ARRAY_SIZE(bufferInvalid), NULL);
154c2c66affSColin Finck 
155c2c66affSColin Finck     /* A random sample of DceErrorInqText */
156c2c66affSColin Finck     /* 0 is success */
157c2c66affSColin Finck     ok ((DceErrorInqTextA (0, (unsigned char*)buffer) == RPC_S_OK),
158c2c66affSColin Finck             "DceErrorInqTextA(0...)\n");
159c2c66affSColin Finck     /* A real RPC_S error */
160c2c66affSColin Finck     ok ((DceErrorInqTextA (RPC_S_INVALID_STRING_UUID, (unsigned char*)buffer) == RPC_S_OK),
161c2c66affSColin Finck             "DceErrorInqTextA(valid...)\n");
162c2c66affSColin Finck 
163c2c66affSColin Finck     if (dwCount)
164c2c66affSColin Finck     {
165c2c66affSColin Finck         /* A message for which FormatMessage should fail
166c2c66affSColin Finck          * which should return RPC_S_OK and the
167c2c66affSColin Finck          * fixed "not valid" message
168c2c66affSColin Finck          */
169c2c66affSColin Finck         ok ((DceErrorInqTextA (35, (unsigned char*)buffer) == RPC_S_OK &&
170c2c66affSColin Finck                     strcmp (buffer, bufferInvalid) == 0),
171c2c66affSColin Finck                 "DceErrorInqTextA(unformattable...)\n");
172c2c66affSColin Finck         /* One for which FormatMessage should succeed but
173c2c66affSColin Finck          * DceErrorInqText should "fail"
174c2c66affSColin Finck          * 3814 is generally quite a long message
175c2c66affSColin Finck          */
176c2c66affSColin Finck         ok ((DceErrorInqTextA (3814, (unsigned char*)buffer) == RPC_S_OK &&
177c2c66affSColin Finck                     strcmp (buffer, bufferInvalid) == 0),
178c2c66affSColin Finck                 "DceErrorInqTextA(deviation...)\n");
179c2c66affSColin Finck     }
180c2c66affSColin Finck     else
181c2c66affSColin Finck         ok (0, "Cannot set up for DceErrorInqText\n");
182c2c66affSColin Finck }
183c2c66affSColin Finck 
184c2c66affSColin Finck static RPC_DISPATCH_FUNCTION IFoo_table[] =
185c2c66affSColin Finck {
186c2c66affSColin Finck     0
187c2c66affSColin Finck };
188c2c66affSColin Finck 
189c2c66affSColin Finck static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable =
190c2c66affSColin Finck {
191c2c66affSColin Finck     0,
192c2c66affSColin Finck     IFoo_table
193c2c66affSColin Finck };
194c2c66affSColin Finck 
195c2c66affSColin Finck static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface =
196c2c66affSColin Finck {
197c2c66affSColin Finck     sizeof(RPC_SERVER_INTERFACE),
198c2c66affSColin Finck     {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}},
199c2c66affSColin Finck     {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
200c2c66affSColin Finck     &IFoo_v0_0_DispatchTable,
201c2c66affSColin Finck     0,
202c2c66affSColin Finck     0,
203c2c66affSColin Finck     0,
204c2c66affSColin Finck     0,
205c2c66affSColin Finck     0,
206c2c66affSColin Finck };
207c2c66affSColin Finck 
208c2c66affSColin Finck static RPC_IF_HANDLE IFoo_v0_0_s_ifspec = (RPC_IF_HANDLE)& IFoo___RpcServerInterface;
209c2c66affSColin Finck 
test_rpc_ncacn_ip_tcp(void)210c2c66affSColin Finck static void test_rpc_ncacn_ip_tcp(void)
211c2c66affSColin Finck {
212c2c66affSColin Finck     RPC_STATUS status;
213c2c66affSColin Finck     unsigned char *binding, *principal;
214c2c66affSColin Finck     handle_t IFoo_IfHandle;
215c2c66affSColin Finck     ULONG level, authnsvc, authzsvc;
216c2c66affSColin Finck     RPC_AUTH_IDENTITY_HANDLE identity;
217c2c66affSColin Finck     static unsigned char foo[] = "foo";
218c2c66affSColin Finck     static unsigned char ncacn_ip_tcp[] = "ncacn_ip_tcp";
219c2c66affSColin Finck     static unsigned char address[] = "127.0.0.1";
220c2c66affSColin Finck     static unsigned char endpoint[] = "4114";
221c2c66affSColin Finck     static unsigned char spn[] = "principal";
222c2c66affSColin Finck 
223c2c66affSColin Finck     status = RpcNetworkIsProtseqValidA(foo);
224c2c66affSColin Finck     ok(status == RPC_S_INVALID_RPC_PROTSEQ, "return wrong\n");
225c2c66affSColin Finck 
226c2c66affSColin Finck     status = RpcNetworkIsProtseqValidA(ncacn_ip_tcp);
227c2c66affSColin Finck     ok(status == RPC_S_OK, "return wrong\n");
228c2c66affSColin Finck 
229c2c66affSColin Finck     status = RpcMgmtStopServerListening(NULL);
230c2c66affSColin Finck     ok(status == RPC_S_NOT_LISTENING,
231c2c66affSColin Finck        "wrong RpcMgmtStopServerListening error (%u)\n", status);
232c2c66affSColin Finck 
233c2c66affSColin Finck     status = RpcMgmtWaitServerListen();
234c2c66affSColin Finck     ok(status == RPC_S_NOT_LISTENING,
235c2c66affSColin Finck        "wrong RpcMgmtWaitServerListen error status (%u)\n", status);
236c2c66affSColin Finck 
237c2c66affSColin Finck     status = RpcServerListen(1, 20, FALSE);
238c2c66affSColin Finck     ok(status == RPC_S_NO_PROTSEQS_REGISTERED,
239c2c66affSColin Finck        "wrong RpcServerListen error (%u)\n", status);
240c2c66affSColin Finck 
241c2c66affSColin Finck     status = RpcServerUseProtseqEpA(ncacn_ip_tcp, 20, endpoint, NULL);
242c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerUseProtseqEp failed (%u)\n", status);
243c2c66affSColin Finck 
244c2c66affSColin Finck     status = RpcServerRegisterIf(IFoo_v0_0_s_ifspec, NULL, NULL);
245c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerRegisterIf failed (%u)\n", status);
246c2c66affSColin Finck 
247c2c66affSColin Finck     status = RpcServerListen(1, 20, TRUE);
248c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerListen failed (%u)\n", status);
249c2c66affSColin Finck 
250c2c66affSColin Finck     status = RpcServerListen(1, 20, TRUE);
251c2c66affSColin Finck     ok(status == RPC_S_ALREADY_LISTENING,
252c2c66affSColin Finck        "wrong RpcServerListen error (%u)\n", status);
253c2c66affSColin Finck 
254c2c66affSColin Finck     status = RpcStringBindingComposeA(NULL, ncacn_ip_tcp, address,
255c2c66affSColin Finck                                      endpoint, NULL, &binding);
256c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%u)\n", status);
257c2c66affSColin Finck 
258c2c66affSColin Finck     status = RpcBindingFromStringBindingA(binding, &IFoo_IfHandle);
259c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%u)\n",
260c2c66affSColin Finck        status);
261c2c66affSColin Finck 
262c2c66affSColin Finck     status = RpcBindingSetAuthInfoA(IFoo_IfHandle, NULL, RPC_C_AUTHN_LEVEL_NONE,
263c2c66affSColin Finck                                    RPC_C_AUTHN_WINNT, NULL, RPC_C_AUTHZ_NAME);
264c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingSetAuthInfo failed (%u)\n", status);
265c2c66affSColin Finck 
266c2c66affSColin Finck     status = RpcBindingInqAuthInfoA(IFoo_IfHandle, NULL, NULL, NULL, NULL, NULL);
267c2c66affSColin Finck     ok(status == RPC_S_BINDING_HAS_NO_AUTH, "RpcBindingInqAuthInfo failed (%u)\n",
268c2c66affSColin Finck        status);
269c2c66affSColin Finck 
270c2c66affSColin Finck     status = RpcBindingSetAuthInfoA(IFoo_IfHandle, spn, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
271c2c66affSColin Finck                                    RPC_C_AUTHN_WINNT, NULL, RPC_C_AUTHZ_NAME);
272c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingSetAuthInfo failed (%u)\n", status);
273c2c66affSColin Finck 
274c2c66affSColin Finck     level = authnsvc = authzsvc = 0;
275c2c66affSColin Finck     principal = (unsigned char *)0xdeadbeef;
276c2c66affSColin Finck     identity = (RPC_AUTH_IDENTITY_HANDLE *)0xdeadbeef;
277c2c66affSColin Finck     status = RpcBindingInqAuthInfoA(IFoo_IfHandle, &principal, &level, &authnsvc,
278c2c66affSColin Finck                                    &identity, &authzsvc);
279c2c66affSColin Finck 
280c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingInqAuthInfo failed (%u)\n", status);
281c2c66affSColin Finck     ok(identity == NULL, "expected NULL identity, got %p\n", identity);
282c2c66affSColin Finck     ok(principal != (unsigned char *)0xdeadbeef, "expected valid principal, got %p\n", principal);
283c2c66affSColin Finck     ok(level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY, "expected RPC_C_AUTHN_LEVEL_PKT_PRIVACY, got %d\n", level);
284c2c66affSColin Finck     ok(authnsvc == RPC_C_AUTHN_WINNT, "expected RPC_C_AUTHN_WINNT, got %d\n", authnsvc);
285c2c66affSColin Finck     todo_wine ok(authzsvc == RPC_C_AUTHZ_NAME, "expected RPC_C_AUTHZ_NAME, got %d\n", authzsvc);
286c2c66affSColin Finck     if (status == RPC_S_OK) RpcStringFreeA(&principal);
287c2c66affSColin Finck 
288c2c66affSColin Finck     status = RpcMgmtStopServerListening(NULL);
289c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcMgmtStopServerListening failed (%u)\n",
290c2c66affSColin Finck        status);
291c2c66affSColin Finck 
292c2c66affSColin Finck     status = RpcMgmtStopServerListening(NULL);
293c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcMgmtStopServerListening failed (%u)\n",
294c2c66affSColin Finck        status);
295c2c66affSColin Finck 
296c2c66affSColin Finck     status = RpcServerUnregisterIf(NULL, NULL, FALSE);
297c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerUnregisterIf failed (%u)\n", status);
298c2c66affSColin Finck 
299c2c66affSColin Finck     status = RpcMgmtWaitServerListen();
300c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcMgmtWaitServerListen failed (%u)\n", status);
301c2c66affSColin Finck 
302c2c66affSColin Finck     status = RpcStringFreeA(&binding);
303c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringFree failed (%u)\n", status);
304c2c66affSColin Finck 
305c2c66affSColin Finck     status = RpcBindingFree(&IFoo_IfHandle);
306c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingFree failed (%u)\n", status);
307c2c66affSColin Finck }
308c2c66affSColin Finck 
309c2c66affSColin Finck /* this is what's generated with MS/RPC - it includes an extra 2
310c2c66affSColin Finck  * bytes in the protocol floor */
311c2c66affSColin Finck static const unsigned char tower_data_tcp_ip1[] =
312c2c66affSColin Finck {
313c2c66affSColin Finck     0x05,0x00,0x13,0x00,0x0d,0x00,0xdb,0xf1,
314c2c66affSColin Finck     0xa4,0x47,0xca,0x67,0x10,0xb3,0x1f,0x00,
315c2c66affSColin Finck     0xdd,0x01,0x06,0x62,0xda,0x00,0x00,0x02,
316c2c66affSColin Finck     0x00,0x00,0x00,0x13,0x00,0x0d,0x04,0x5d,
317c2c66affSColin Finck     0x88,0x8a,0xeb,0x1c,0xc9,0x11,0x9f,0xe8,
318c2c66affSColin Finck     0x08,0x00,0x2b,0x10,0x48,0x60,0x02,0x00,
319c2c66affSColin Finck     0x02,0x00,0x00,0x00,0x01,0x00,0x0b,0x02,
320c2c66affSColin Finck     0x00,0x00,0x00,0x01,0x00,0x07,0x02,0x00,
321c2c66affSColin Finck     0x00,0x87,0x01,0x00,0x09,0x04,0x00,0x0a,
322c2c66affSColin Finck     0x00,0x00,0x01,
323c2c66affSColin Finck };
324c2c66affSColin Finck /* this is the optimal data that i think should be generated */
325c2c66affSColin Finck static const unsigned char tower_data_tcp_ip2[] =
326c2c66affSColin Finck {
327c2c66affSColin Finck     0x05,0x00,0x13,0x00,0x0d,0x00,0xdb,0xf1,
328c2c66affSColin Finck     0xa4,0x47,0xca,0x67,0x10,0xb3,0x1f,0x00,
329c2c66affSColin Finck     0xdd,0x01,0x06,0x62,0xda,0x00,0x00,0x02,
330c2c66affSColin Finck     0x00,0x00,0x00,0x13,0x00,0x0d,0x04,0x5d,
331c2c66affSColin Finck     0x88,0x8a,0xeb,0x1c,0xc9,0x11,0x9f,0xe8,
332c2c66affSColin Finck     0x08,0x00,0x2b,0x10,0x48,0x60,0x02,0x00,
333c2c66affSColin Finck     0x02,0x00,0x00,0x00,0x01,0x00,0x0b,0x00,
334c2c66affSColin Finck     0x00,0x01,0x00,0x07,0x02,0x00,0x00,0x87,
335c2c66affSColin Finck     0x01,0x00,0x09,0x04,0x00,0x0a,0x00,0x00,
336c2c66affSColin Finck     0x01,
337c2c66affSColin Finck };
338c2c66affSColin Finck 
test_towers(void)339c2c66affSColin Finck static void test_towers(void)
340c2c66affSColin Finck {
341c2c66affSColin Finck     RPC_STATUS ret;
342c2c66affSColin Finck     twr_t *tower;
343c2c66affSColin Finck     static const RPC_SYNTAX_IDENTIFIER mapi_if_id = { { 0xa4f1db00, 0xca47, 0x1067, { 0xb3, 0x1f, 0x00, 0xdd, 0x01, 0x06, 0x62, 0xda } }, { 0, 0 } };
344c2c66affSColin Finck     static const RPC_SYNTAX_IDENTIFIER ndr_syntax = { { 0x8a885d04, 0x1ceb, 0x11c9, { 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60 } }, { 2, 0 } };
345c2c66affSColin Finck     RPC_SYNTAX_IDENTIFIER object, syntax;
346c2c66affSColin Finck     char *protseq, *endpoint, *address;
347c2c66affSColin Finck     BOOL same;
348c2c66affSColin Finck 
349c2c66affSColin Finck     ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_ip_tcp", "135", "10.0.0.1", &tower);
350c2c66affSColin Finck     ok(ret == RPC_S_OK ||
351c2c66affSColin Finck        broken(ret == RPC_S_INVALID_RPC_PROTSEQ), /* Vista */
352c2c66affSColin Finck        "TowerConstruct failed with error %d\n", ret);
353c2c66affSColin Finck     if (ret == RPC_S_INVALID_RPC_PROTSEQ)
354c2c66affSColin Finck     {
355c2c66affSColin Finck         /* Windows Vista fails with this error and crashes if we continue */
356c2c66affSColin Finck         win_skip("TowerConstruct failed, we are most likely on Windows Vista\n");
357c2c66affSColin Finck         return;
358c2c66affSColin Finck     }
359c2c66affSColin Finck 
360c2c66affSColin Finck     /* first check we have the right amount of data */
361c2c66affSColin Finck     ok(tower->tower_length == sizeof(tower_data_tcp_ip1) ||
362c2c66affSColin Finck        tower->tower_length == sizeof(tower_data_tcp_ip2),
363c2c66affSColin Finck         "Wrong size of tower %d\n", tower->tower_length);
364c2c66affSColin Finck 
365c2c66affSColin Finck     /* then do a byte-by-byte comparison */
366c2c66affSColin Finck     same = ((tower->tower_length == sizeof(tower_data_tcp_ip1)) &&
367c2c66affSColin Finck             !memcmp(&tower->tower_octet_string, tower_data_tcp_ip1, sizeof(tower_data_tcp_ip1))) ||
368c2c66affSColin Finck            ((tower->tower_length == sizeof(tower_data_tcp_ip2)) &&
369c2c66affSColin Finck             !memcmp(&tower->tower_octet_string, tower_data_tcp_ip2, sizeof(tower_data_tcp_ip2)));
370c2c66affSColin Finck 
371c2c66affSColin Finck     ok(same, "Tower data differs\n");
372c2c66affSColin Finck     if (!same)
373c2c66affSColin Finck     {
374c2c66affSColin Finck         unsigned32 i;
375c2c66affSColin Finck         for (i = 0; i < tower->tower_length; i++)
376c2c66affSColin Finck         {
377c2c66affSColin Finck             if (i % 8 == 0) printf("    ");
378c2c66affSColin Finck             printf("0x%02x,", tower->tower_octet_string[i]);
379c2c66affSColin Finck             if (i % 8 == 7) printf("\n");
380c2c66affSColin Finck         }
381c2c66affSColin Finck         printf("\n");
382c2c66affSColin Finck     }
383c2c66affSColin Finck 
384c2c66affSColin Finck     ret = TowerExplode(tower, &object, &syntax, &protseq, &endpoint, &address);
385c2c66affSColin Finck     ok(ret == RPC_S_OK, "TowerExplode failed with error %d\n", ret);
386c2c66affSColin Finck     ok(!memcmp(&object, &mapi_if_id, sizeof(mapi_if_id)), "object id didn't match\n");
387c2c66affSColin Finck     ok(!memcmp(&syntax, &ndr_syntax, sizeof(syntax)), "syntax id didn't match\n");
388c2c66affSColin Finck     ok(!strcmp(protseq, "ncacn_ip_tcp"), "protseq was \"%s\" instead of \"ncacn_ip_tcp\"\n", protseq);
389c2c66affSColin Finck     ok(!strcmp(endpoint, "135"), "endpoint was \"%s\" instead of \"135\"\n", endpoint);
390c2c66affSColin Finck     ok(!strcmp(address, "10.0.0.1"), "address was \"%s\" instead of \"10.0.0.1\"\n", address);
391c2c66affSColin Finck 
392c2c66affSColin Finck     I_RpcFree(protseq);
393c2c66affSColin Finck     I_RpcFree(endpoint);
394c2c66affSColin Finck     I_RpcFree(address);
395c2c66affSColin Finck 
396c2c66affSColin Finck     ret = TowerExplode(tower, NULL, NULL, NULL, NULL, NULL);
397c2c66affSColin Finck     ok(ret == RPC_S_OK, "TowerExplode failed with error %d\n", ret);
398c2c66affSColin Finck 
399c2c66affSColin Finck     I_RpcFree(tower);
400c2c66affSColin Finck 
401c2c66affSColin Finck     /* test the behaviour for ip_tcp with name instead of dotted IP notation */
402c2c66affSColin Finck     ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_ip_tcp", "135", "localhost", &tower);
403c2c66affSColin Finck     ok(ret == RPC_S_OK, "TowerConstruct failed with error %d\n", ret);
404c2c66affSColin Finck     ret = TowerExplode(tower, NULL, NULL, NULL, NULL, &address);
405c2c66affSColin Finck     ok(ret == RPC_S_OK, "TowerExplode failed with error %d\n", ret);
406c2c66affSColin Finck     ok(!strcmp(address, "0.0.0.0") ||
407c2c66affSColin Finck        broken(!strcmp(address, "255.255.255.255")),
408c2c66affSColin Finck        "address was \"%s\" instead of \"0.0.0.0\"\n", address);
409c2c66affSColin Finck 
410c2c66affSColin Finck     I_RpcFree(address);
411c2c66affSColin Finck     I_RpcFree(tower);
412c2c66affSColin Finck 
413c2c66affSColin Finck     /* test the behaviour for np with no address */
414c2c66affSColin Finck     ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_np", "\\pipe\\test", NULL, &tower);
415c2c66affSColin Finck     ok(ret == RPC_S_OK, "TowerConstruct failed with error %d\n", ret);
416c2c66affSColin Finck     ret = TowerExplode(tower, NULL, NULL, NULL, NULL, &address);
417c2c66affSColin Finck     ok(ret == RPC_S_OK ||
418c2c66affSColin Finck        broken(ret != RPC_S_OK), /* win2k, indeterminate */
419c2c66affSColin Finck        "TowerExplode failed with error %d\n", ret);
420c2c66affSColin Finck     /* Windows XP SP3 sets address to NULL */
421c2c66affSColin Finck     ok(!address || !strcmp(address, ""), "address was \"%s\" instead of \"\" or NULL (XP SP3)\n", address);
422c2c66affSColin Finck 
423c2c66affSColin Finck     I_RpcFree(address);
424c2c66affSColin Finck     I_RpcFree(tower);
425c2c66affSColin Finck }
426c2c66affSColin Finck 
test_I_RpcMapWin32Status(void)427c2c66affSColin Finck static void test_I_RpcMapWin32Status(void)
428c2c66affSColin Finck {
429c2c66affSColin Finck     LONG win32status;
430c2c66affSColin Finck     RPC_STATUS rpc_status;
431c2c66affSColin Finck     BOOL w2k3_up = FALSE;
432c2c66affSColin Finck 
433c2c66affSColin Finck     /* Windows 2003 and above return STATUS_UNSUCCESSFUL if given an unknown status */
434c2c66affSColin Finck     win32status = I_RpcMapWin32Status(9999);
435c2c66affSColin Finck     if (win32status == STATUS_UNSUCCESSFUL)
436c2c66affSColin Finck         w2k3_up = TRUE;
437c2c66affSColin Finck 
438c2c66affSColin Finck     /* On Windows XP-SP1 and below some statuses are not mapped and return
439c2c66affSColin Finck      * the given status
440c2c66affSColin Finck      */
441c2c66affSColin Finck     for (rpc_status = 0; rpc_status < 10000; rpc_status++)
442c2c66affSColin Finck     {
443c2c66affSColin Finck         LONG expected_win32status;
444c2c66affSColin Finck         BOOL missing = FALSE;
445c2c66affSColin Finck 
446c2c66affSColin Finck         win32status = I_RpcMapWin32Status(rpc_status);
447c2c66affSColin Finck         switch (rpc_status)
448c2c66affSColin Finck         {
449c2c66affSColin Finck         case ERROR_SUCCESS: expected_win32status = ERROR_SUCCESS; break;
450c2c66affSColin Finck         case ERROR_ACCESS_DENIED: expected_win32status = STATUS_ACCESS_DENIED; break;
451c2c66affSColin Finck         case ERROR_INVALID_HANDLE: expected_win32status = RPC_NT_SS_CONTEXT_MISMATCH; break;
452c2c66affSColin Finck         case ERROR_OUTOFMEMORY: expected_win32status = STATUS_NO_MEMORY; break;
453c2c66affSColin Finck         case ERROR_INVALID_PARAMETER: expected_win32status = STATUS_INVALID_PARAMETER; break;
454c2c66affSColin Finck         case ERROR_INSUFFICIENT_BUFFER: expected_win32status = STATUS_BUFFER_TOO_SMALL; break;
455c2c66affSColin Finck         case ERROR_MAX_THRDS_REACHED: expected_win32status = STATUS_NO_MEMORY; break;
456c2c66affSColin Finck         case ERROR_NOACCESS: expected_win32status = STATUS_ACCESS_VIOLATION; break;
457c2c66affSColin Finck         case ERROR_NOT_ENOUGH_SERVER_MEMORY: expected_win32status = STATUS_INSUFF_SERVER_RESOURCES; break;
458c2c66affSColin Finck         case ERROR_WRONG_PASSWORD:  expected_win32status = STATUS_WRONG_PASSWORD; missing = TRUE; break;
459c2c66affSColin Finck         case ERROR_INVALID_LOGON_HOURS: expected_win32status = STATUS_INVALID_LOGON_HOURS; missing = TRUE; break;
460c2c66affSColin Finck         case ERROR_PASSWORD_EXPIRED: expected_win32status = STATUS_PASSWORD_EXPIRED; missing = TRUE; break;
461c2c66affSColin Finck         case ERROR_ACCOUNT_DISABLED: expected_win32status = STATUS_ACCOUNT_DISABLED; missing = TRUE; break;
462c2c66affSColin Finck         case ERROR_INVALID_SECURITY_DESCR: expected_win32status = STATUS_INVALID_SECURITY_DESCR; break;
463c2c66affSColin Finck         case RPC_S_INVALID_STRING_BINDING: expected_win32status = RPC_NT_INVALID_STRING_BINDING; break;
464c2c66affSColin Finck         case RPC_S_WRONG_KIND_OF_BINDING: expected_win32status = RPC_NT_WRONG_KIND_OF_BINDING; break;
465c2c66affSColin Finck         case RPC_S_INVALID_BINDING: expected_win32status = RPC_NT_INVALID_BINDING; break;
466c2c66affSColin Finck         case RPC_S_PROTSEQ_NOT_SUPPORTED: expected_win32status = RPC_NT_PROTSEQ_NOT_SUPPORTED; break;
467c2c66affSColin Finck         case RPC_S_INVALID_RPC_PROTSEQ: expected_win32status = RPC_NT_INVALID_RPC_PROTSEQ; break;
468c2c66affSColin Finck         case RPC_S_INVALID_STRING_UUID: expected_win32status = RPC_NT_INVALID_STRING_UUID; break;
469c2c66affSColin Finck         case RPC_S_INVALID_ENDPOINT_FORMAT: expected_win32status = RPC_NT_INVALID_ENDPOINT_FORMAT; break;
470c2c66affSColin Finck         case RPC_S_INVALID_NET_ADDR: expected_win32status = RPC_NT_INVALID_NET_ADDR; break;
471c2c66affSColin Finck         case RPC_S_NO_ENDPOINT_FOUND: expected_win32status = RPC_NT_NO_ENDPOINT_FOUND; break;
472c2c66affSColin Finck         case RPC_S_INVALID_TIMEOUT: expected_win32status = RPC_NT_INVALID_TIMEOUT; break;
473c2c66affSColin Finck         case RPC_S_OBJECT_NOT_FOUND: expected_win32status = RPC_NT_OBJECT_NOT_FOUND; break;
474c2c66affSColin Finck         case RPC_S_ALREADY_REGISTERED: expected_win32status = RPC_NT_ALREADY_REGISTERED; break;
475c2c66affSColin Finck         case RPC_S_TYPE_ALREADY_REGISTERED: expected_win32status = RPC_NT_TYPE_ALREADY_REGISTERED; break;
476c2c66affSColin Finck         case RPC_S_ALREADY_LISTENING: expected_win32status = RPC_NT_ALREADY_LISTENING; break;
477c2c66affSColin Finck         case RPC_S_NO_PROTSEQS_REGISTERED: expected_win32status = RPC_NT_NO_PROTSEQS_REGISTERED; break;
478c2c66affSColin Finck         case RPC_S_NOT_LISTENING: expected_win32status = RPC_NT_NOT_LISTENING; break;
479c2c66affSColin Finck         case RPC_S_UNKNOWN_MGR_TYPE: expected_win32status = RPC_NT_UNKNOWN_MGR_TYPE; break;
480c2c66affSColin Finck         case RPC_S_UNKNOWN_IF: expected_win32status = RPC_NT_UNKNOWN_IF; break;
481c2c66affSColin Finck         case RPC_S_NO_BINDINGS: expected_win32status = RPC_NT_NO_BINDINGS; break;
482c2c66affSColin Finck         case RPC_S_NO_PROTSEQS: expected_win32status = RPC_NT_NO_PROTSEQS; break;
483c2c66affSColin Finck         case RPC_S_CANT_CREATE_ENDPOINT: expected_win32status = RPC_NT_CANT_CREATE_ENDPOINT; break;
484c2c66affSColin Finck         case RPC_S_OUT_OF_RESOURCES: expected_win32status = RPC_NT_OUT_OF_RESOURCES; break;
485c2c66affSColin Finck         case RPC_S_SERVER_UNAVAILABLE: expected_win32status = RPC_NT_SERVER_UNAVAILABLE; break;
486c2c66affSColin Finck         case RPC_S_SERVER_TOO_BUSY: expected_win32status = RPC_NT_SERVER_TOO_BUSY; break;
487c2c66affSColin Finck         case RPC_S_INVALID_NETWORK_OPTIONS: expected_win32status = RPC_NT_INVALID_NETWORK_OPTIONS; break;
488c2c66affSColin Finck         case RPC_S_NO_CALL_ACTIVE: expected_win32status = RPC_NT_NO_CALL_ACTIVE; break;
489c2c66affSColin Finck         case RPC_S_CALL_FAILED: expected_win32status = RPC_NT_CALL_FAILED; break;
490c2c66affSColin Finck         case RPC_S_CALL_FAILED_DNE: expected_win32status = RPC_NT_CALL_FAILED_DNE; break;
491c2c66affSColin Finck         case RPC_S_PROTOCOL_ERROR: expected_win32status = RPC_NT_PROTOCOL_ERROR; break;
492c2c66affSColin Finck         case RPC_S_UNSUPPORTED_TRANS_SYN: expected_win32status = RPC_NT_UNSUPPORTED_TRANS_SYN; break;
493c2c66affSColin Finck         case RPC_S_UNSUPPORTED_TYPE: expected_win32status = RPC_NT_UNSUPPORTED_TYPE; break;
494c2c66affSColin Finck         case RPC_S_INVALID_TAG: expected_win32status = RPC_NT_INVALID_TAG; break;
495c2c66affSColin Finck         case RPC_S_INVALID_BOUND: expected_win32status = RPC_NT_INVALID_BOUND; break;
496c2c66affSColin Finck         case RPC_S_NO_ENTRY_NAME: expected_win32status = RPC_NT_NO_ENTRY_NAME; break;
497c2c66affSColin Finck         case RPC_S_INVALID_NAME_SYNTAX: expected_win32status = RPC_NT_INVALID_NAME_SYNTAX; break;
498c2c66affSColin Finck         case RPC_S_UNSUPPORTED_NAME_SYNTAX: expected_win32status = RPC_NT_UNSUPPORTED_NAME_SYNTAX; break;
499c2c66affSColin Finck         case RPC_S_UUID_NO_ADDRESS: expected_win32status = RPC_NT_UUID_NO_ADDRESS; break;
500c2c66affSColin Finck         case RPC_S_DUPLICATE_ENDPOINT: expected_win32status = RPC_NT_DUPLICATE_ENDPOINT; break;
501c2c66affSColin Finck         case RPC_S_UNKNOWN_AUTHN_TYPE: expected_win32status = RPC_NT_UNKNOWN_AUTHN_TYPE; break;
502c2c66affSColin Finck         case RPC_S_MAX_CALLS_TOO_SMALL: expected_win32status = RPC_NT_MAX_CALLS_TOO_SMALL; break;
503c2c66affSColin Finck         case RPC_S_STRING_TOO_LONG: expected_win32status = RPC_NT_STRING_TOO_LONG; break;
504c2c66affSColin Finck         case RPC_S_PROTSEQ_NOT_FOUND: expected_win32status = RPC_NT_PROTSEQ_NOT_FOUND; break;
505c2c66affSColin Finck         case RPC_S_PROCNUM_OUT_OF_RANGE: expected_win32status = RPC_NT_PROCNUM_OUT_OF_RANGE; break;
506c2c66affSColin Finck         case RPC_S_BINDING_HAS_NO_AUTH: expected_win32status = RPC_NT_BINDING_HAS_NO_AUTH; break;
507c2c66affSColin Finck         case RPC_S_UNKNOWN_AUTHN_SERVICE: expected_win32status = RPC_NT_UNKNOWN_AUTHN_SERVICE; break;
508c2c66affSColin Finck         case RPC_S_UNKNOWN_AUTHN_LEVEL: expected_win32status = RPC_NT_UNKNOWN_AUTHN_LEVEL; break;
509c2c66affSColin Finck         case RPC_S_INVALID_AUTH_IDENTITY: expected_win32status = RPC_NT_INVALID_AUTH_IDENTITY; break;
510c2c66affSColin Finck         case RPC_S_UNKNOWN_AUTHZ_SERVICE: expected_win32status = RPC_NT_UNKNOWN_AUTHZ_SERVICE; break;
511c2c66affSColin Finck         case EPT_S_INVALID_ENTRY: expected_win32status = EPT_NT_INVALID_ENTRY; break;
512c2c66affSColin Finck         case EPT_S_CANT_PERFORM_OP: expected_win32status = EPT_NT_CANT_PERFORM_OP; break;
513c2c66affSColin Finck         case EPT_S_NOT_REGISTERED: expected_win32status = EPT_NT_NOT_REGISTERED; break;
514c2c66affSColin Finck         case EPT_S_CANT_CREATE: expected_win32status = EPT_NT_CANT_CREATE; break;
515c2c66affSColin Finck         case RPC_S_NOTHING_TO_EXPORT: expected_win32status = RPC_NT_NOTHING_TO_EXPORT; break;
516c2c66affSColin Finck         case RPC_S_INCOMPLETE_NAME: expected_win32status = RPC_NT_INCOMPLETE_NAME; break;
517c2c66affSColin Finck         case RPC_S_INVALID_VERS_OPTION: expected_win32status = RPC_NT_INVALID_VERS_OPTION; break;
518c2c66affSColin Finck         case RPC_S_NO_MORE_MEMBERS: expected_win32status = RPC_NT_NO_MORE_MEMBERS; break;
519c2c66affSColin Finck         case RPC_S_NOT_ALL_OBJS_UNEXPORTED: expected_win32status = RPC_NT_NOT_ALL_OBJS_UNEXPORTED; break;
520c2c66affSColin Finck         case RPC_S_INTERFACE_NOT_FOUND: expected_win32status = RPC_NT_INTERFACE_NOT_FOUND; break;
521c2c66affSColin Finck         case RPC_S_ENTRY_ALREADY_EXISTS: expected_win32status = RPC_NT_ENTRY_ALREADY_EXISTS; break;
522c2c66affSColin Finck         case RPC_S_ENTRY_NOT_FOUND: expected_win32status = RPC_NT_ENTRY_NOT_FOUND; break;
523c2c66affSColin Finck         case RPC_S_NAME_SERVICE_UNAVAILABLE: expected_win32status = RPC_NT_NAME_SERVICE_UNAVAILABLE; break;
524c2c66affSColin Finck         case RPC_S_INVALID_NAF_ID: expected_win32status = RPC_NT_INVALID_NAF_ID; break;
525c2c66affSColin Finck         case RPC_S_CANNOT_SUPPORT: expected_win32status = RPC_NT_CANNOT_SUPPORT; break;
526c2c66affSColin Finck         case RPC_S_NO_CONTEXT_AVAILABLE: expected_win32status = RPC_NT_NO_CONTEXT_AVAILABLE; break;
527c2c66affSColin Finck         case RPC_S_INTERNAL_ERROR: expected_win32status = RPC_NT_INTERNAL_ERROR; break;
528c2c66affSColin Finck         case RPC_S_ZERO_DIVIDE: expected_win32status = RPC_NT_ZERO_DIVIDE; break;
529c2c66affSColin Finck         case RPC_S_ADDRESS_ERROR: expected_win32status = RPC_NT_ADDRESS_ERROR; break;
530c2c66affSColin Finck         case RPC_S_FP_DIV_ZERO: expected_win32status = RPC_NT_FP_DIV_ZERO; break;
531c2c66affSColin Finck         case RPC_S_FP_UNDERFLOW: expected_win32status = RPC_NT_FP_UNDERFLOW; break;
532c2c66affSColin Finck         case RPC_S_FP_OVERFLOW: expected_win32status = RPC_NT_FP_OVERFLOW; break;
533c2c66affSColin Finck         case RPC_S_CALL_IN_PROGRESS: expected_win32status = RPC_NT_CALL_IN_PROGRESS; break;
534c2c66affSColin Finck         case RPC_S_NO_MORE_BINDINGS: expected_win32status = RPC_NT_NO_MORE_BINDINGS; break;
535c2c66affSColin Finck         case RPC_S_CALL_CANCELLED: expected_win32status = RPC_NT_CALL_CANCELLED; missing = TRUE; break;
536c2c66affSColin Finck         case RPC_S_INVALID_OBJECT: expected_win32status = RPC_NT_INVALID_OBJECT; break;
537c2c66affSColin Finck         case RPC_S_INVALID_ASYNC_HANDLE: expected_win32status = RPC_NT_INVALID_ASYNC_HANDLE; missing = TRUE; break;
538c2c66affSColin Finck         case RPC_S_INVALID_ASYNC_CALL: expected_win32status = RPC_NT_INVALID_ASYNC_CALL; missing = TRUE; break;
539c2c66affSColin Finck         case RPC_S_GROUP_MEMBER_NOT_FOUND: expected_win32status = RPC_NT_GROUP_MEMBER_NOT_FOUND; break;
540c2c66affSColin Finck         case RPC_X_NO_MORE_ENTRIES: expected_win32status = RPC_NT_NO_MORE_ENTRIES; break;
541c2c66affSColin Finck         case RPC_X_SS_CHAR_TRANS_OPEN_FAIL: expected_win32status = RPC_NT_SS_CHAR_TRANS_OPEN_FAIL; break;
542c2c66affSColin Finck         case RPC_X_SS_CHAR_TRANS_SHORT_FILE: expected_win32status = RPC_NT_SS_CHAR_TRANS_SHORT_FILE; break;
543c2c66affSColin Finck         case RPC_X_SS_IN_NULL_CONTEXT: expected_win32status = RPC_NT_SS_IN_NULL_CONTEXT; break;
544c2c66affSColin Finck         case RPC_X_SS_CONTEXT_DAMAGED: expected_win32status = RPC_NT_SS_CONTEXT_DAMAGED; break;
545c2c66affSColin Finck         case RPC_X_SS_HANDLES_MISMATCH: expected_win32status = RPC_NT_SS_HANDLES_MISMATCH; break;
546c2c66affSColin Finck         case RPC_X_SS_CANNOT_GET_CALL_HANDLE: expected_win32status = RPC_NT_SS_CANNOT_GET_CALL_HANDLE; break;
547c2c66affSColin Finck         case RPC_X_NULL_REF_POINTER: expected_win32status = RPC_NT_NULL_REF_POINTER; break;
548c2c66affSColin Finck         case RPC_X_ENUM_VALUE_OUT_OF_RANGE: expected_win32status = RPC_NT_ENUM_VALUE_OUT_OF_RANGE; break;
549c2c66affSColin Finck         case RPC_X_BYTE_COUNT_TOO_SMALL: expected_win32status = RPC_NT_BYTE_COUNT_TOO_SMALL; break;
550c2c66affSColin Finck         case RPC_X_BAD_STUB_DATA: expected_win32status = RPC_NT_BAD_STUB_DATA; break;
551c2c66affSColin Finck         case RPC_X_PIPE_CLOSED: expected_win32status = RPC_NT_PIPE_CLOSED; missing = TRUE; break;
552c2c66affSColin Finck         case RPC_X_PIPE_DISCIPLINE_ERROR: expected_win32status = RPC_NT_PIPE_DISCIPLINE_ERROR; missing = TRUE; break;
553c2c66affSColin Finck         case RPC_X_PIPE_EMPTY: expected_win32status = RPC_NT_PIPE_EMPTY; missing = TRUE; break;
554c2c66affSColin Finck         case ERROR_PASSWORD_MUST_CHANGE: expected_win32status = STATUS_PASSWORD_MUST_CHANGE; missing = TRUE; break;
555c2c66affSColin Finck         case ERROR_ACCOUNT_LOCKED_OUT: expected_win32status = STATUS_ACCOUNT_LOCKED_OUT; missing = TRUE; break;
556c2c66affSColin Finck         default:
557c2c66affSColin Finck             if (w2k3_up)
558c2c66affSColin Finck                 expected_win32status = STATUS_UNSUCCESSFUL;
559c2c66affSColin Finck             else
560c2c66affSColin Finck                 expected_win32status = rpc_status;
561c2c66affSColin Finck         }
562c2c66affSColin Finck 
563c2c66affSColin Finck         ok(win32status == expected_win32status ||
564c2c66affSColin Finck             broken(missing && win32status == rpc_status),
565c2c66affSColin Finck             "I_RpcMapWin32Status(%d) should have returned 0x%x instead of 0x%x%s\n",
566c2c66affSColin Finck             rpc_status, expected_win32status, win32status,
567c2c66affSColin Finck             broken(missing) ? " (or have returned with the given status)" : "");
568c2c66affSColin Finck     }
569c2c66affSColin Finck }
570c2c66affSColin Finck 
test_RpcStringBindingParseA(void)571c2c66affSColin Finck static void test_RpcStringBindingParseA(void)
572c2c66affSColin Finck {
573c2c66affSColin Finck     static unsigned char valid_binding[] = "00000000-0000-0000-c000-000000000046@ncacn_np:.[endpoint=\\pipe\\test]";
574c2c66affSColin Finck     static unsigned char valid_binding2[] = "00000000-0000-0000-c000-000000000046@ncacn_np:.[\\pipe\\test]";
575c2c66affSColin Finck     static unsigned char invalid_uuid_binding[] = "{00000000-0000-0000-c000-000000000046}@ncacn_np:.[endpoint=\\pipe\\test]";
576c2c66affSColin Finck     static unsigned char invalid_ep_binding[] = "00000000-0000-0000-c000-000000000046@ncacn_np:.[endpoint=test]";
577c2c66affSColin Finck     static unsigned char invalid_binding[] = "00000000-0000-0000-c000-000000000046@ncacn_np";
578c2c66affSColin Finck     RPC_STATUS status;
579c2c66affSColin Finck     unsigned char *uuid;
580c2c66affSColin Finck     unsigned char *protseq;
581c2c66affSColin Finck     unsigned char *network_addr;
582c2c66affSColin Finck     unsigned char *endpoint;
583c2c66affSColin Finck     unsigned char *options;
584c2c66affSColin Finck 
585c2c66affSColin Finck     /* test all parameters */
586c2c66affSColin Finck     status = RpcStringBindingParseA(valid_binding, &uuid, &protseq, &network_addr, &endpoint, &options);
587c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingParseA failed with error %d\n", status);
588c2c66affSColin Finck     ok(!strcmp((char *)uuid, "00000000-0000-0000-c000-000000000046"), "uuid should have been 00000000-0000-0000-C000-000000000046 instead of %s\n", uuid);
589c2c66affSColin Finck     ok(!strcmp((char *)protseq, "ncacn_np"), "protseq should have been ncacn_np instead of %s\n", protseq);
590c2c66affSColin Finck     ok(!strcmp((char *)network_addr, "."), "network_addr should have been . instead of %s\n", network_addr);
591c2c66affSColin Finck     ok(!strcmp((char *)endpoint, "pipetest"), "endpoint should have been pipetest instead of %s\n", endpoint);
592c2c66affSColin Finck     if (options)
593c2c66affSColin Finck         ok(!strcmp((char *)options, ""), "options should have been \"\" of \"%s\"\n", options);
594c2c66affSColin Finck     else
595c2c66affSColin Finck         todo_wine ok(FALSE, "options is NULL\n");
596c2c66affSColin Finck     RpcStringFreeA(&uuid);
597c2c66affSColin Finck     RpcStringFreeA(&protseq);
598c2c66affSColin Finck     RpcStringFreeA(&network_addr);
599c2c66affSColin Finck     RpcStringFreeA(&endpoint);
600c2c66affSColin Finck     RpcStringFreeA(&options);
601c2c66affSColin Finck 
602c2c66affSColin Finck     /* test all parameters with different type of string binding */
603c2c66affSColin Finck     status = RpcStringBindingParseA(valid_binding2, &uuid, &protseq, &network_addr, &endpoint, &options);
604c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingParseA failed with error %d\n", status);
605c2c66affSColin Finck     ok(!strcmp((char *)uuid, "00000000-0000-0000-c000-000000000046"), "uuid should have been 00000000-0000-0000-C000-000000000046 instead of %s\n", uuid);
606c2c66affSColin Finck     ok(!strcmp((char *)protseq, "ncacn_np"), "protseq should have been ncacn_np instead of %s\n", protseq);
607c2c66affSColin Finck     ok(!strcmp((char *)network_addr, "."), "network_addr should have been . instead of %s\n", network_addr);
608c2c66affSColin Finck     ok(!strcmp((char *)endpoint, "pipetest"), "endpoint should have been pipetest instead of %s\n", endpoint);
609c2c66affSColin Finck     if (options)
610c2c66affSColin Finck         ok(!strcmp((char *)options, ""), "options should have been \"\" of \"%s\"\n", options);
611c2c66affSColin Finck     else
612c2c66affSColin Finck         todo_wine ok(FALSE, "options is NULL\n");
613c2c66affSColin Finck     RpcStringFreeA(&uuid);
614c2c66affSColin Finck     RpcStringFreeA(&protseq);
615c2c66affSColin Finck     RpcStringFreeA(&network_addr);
616c2c66affSColin Finck     RpcStringFreeA(&endpoint);
617c2c66affSColin Finck     RpcStringFreeA(&options);
618c2c66affSColin Finck 
619c2c66affSColin Finck     /* test with as many parameters NULL as possible */
620c2c66affSColin Finck     status = RpcStringBindingParseA(valid_binding, NULL, &protseq, NULL, NULL, NULL);
621c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingParseA failed with error %d\n", status);
622c2c66affSColin Finck     ok(!strcmp((char *)protseq, "ncacn_np"), "protseq should have been ncacn_np instead of %s\n", protseq);
623c2c66affSColin Finck     RpcStringFreeA(&protseq);
624c2c66affSColin Finck 
625c2c66affSColin Finck     /* test with invalid uuid */
626c2c66affSColin Finck     status = RpcStringBindingParseA(invalid_uuid_binding, NULL, &protseq, NULL, NULL, NULL);
627c2c66affSColin Finck     ok(status == RPC_S_INVALID_STRING_UUID, "RpcStringBindingParseA should have returned RPC_S_INVALID_STRING_UUID instead of %d\n", status);
628c2c66affSColin Finck     ok(protseq == NULL, "protseq was %p instead of NULL\n", protseq);
629c2c66affSColin Finck 
630c2c66affSColin Finck     /* test with invalid endpoint */
631c2c66affSColin Finck     status = RpcStringBindingParseA(invalid_ep_binding, NULL, &protseq, NULL, NULL, NULL);
632c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingParseA failed with error %d\n", status);
633c2c66affSColin Finck     RpcStringFreeA(&protseq);
634c2c66affSColin Finck 
635c2c66affSColin Finck     /* test with invalid binding */
636c2c66affSColin Finck     status = RpcStringBindingParseA(invalid_binding, &uuid, &protseq, &network_addr, &endpoint, &options);
637c2c66affSColin Finck     ok(status == RPC_S_INVALID_STRING_BINDING, "RpcStringBindingParseA should have returned RPC_S_INVALID_STRING_BINDING instead of %d\n", status);
638c2c66affSColin Finck     ok(uuid == NULL, "uuid was %p instead of NULL\n", uuid);
639c2c66affSColin Finck     if (uuid)
640c2c66affSColin Finck         RpcStringFreeA(&uuid);
641c2c66affSColin Finck     ok(protseq == NULL, "protseq was %p instead of NULL\n", protseq);
642c2c66affSColin Finck     ok(network_addr == NULL, "network_addr was %p instead of NULL\n", network_addr);
643c2c66affSColin Finck     if (network_addr)
644c2c66affSColin Finck         RpcStringFreeA(&network_addr);
645c2c66affSColin Finck     ok(endpoint == NULL, "endpoint was %p instead of NULL\n", endpoint);
646c2c66affSColin Finck     ok(options == NULL, "options was %p instead of NULL\n", options);
647c2c66affSColin Finck }
648c2c66affSColin Finck 
test_RpcExceptionFilter(const char * func_name)649f2f9161aSAmine Khaldi static void test_RpcExceptionFilter(const char *func_name)
650c2c66affSColin Finck {
651c2c66affSColin Finck     ULONG exception;
652c2c66affSColin Finck     int retval;
653f2f9161aSAmine Khaldi     int (WINAPI *pRpcExceptionFilter)(ULONG) = (void *)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), func_name);
654c2c66affSColin Finck 
655f2f9161aSAmine Khaldi     if (!pRpcExceptionFilter)
656c2c66affSColin Finck     {
657f2f9161aSAmine Khaldi         win_skip("%s not exported\n", func_name);
658c2c66affSColin Finck         return;
659c2c66affSColin Finck     }
660c2c66affSColin Finck 
661c2c66affSColin Finck     for (exception = 0; exception < STATUS_REG_NAT_CONSUMPTION; exception++)
662c2c66affSColin Finck     {
663c2c66affSColin Finck         /* skip over uninteresting bits of the number space */
664c2c66affSColin Finck         if (exception == 2000) exception = 0x40000000;
665c2c66affSColin Finck         if (exception == 0x40000005) exception = 0x80000000;
666c2c66affSColin Finck         if (exception == 0x80000005) exception = 0xc0000000;
667c2c66affSColin Finck 
668f2f9161aSAmine Khaldi         retval = pRpcExceptionFilter(exception);
669c2c66affSColin Finck         switch (exception)
670c2c66affSColin Finck         {
671c2c66affSColin Finck         case STATUS_DATATYPE_MISALIGNMENT:
672c2c66affSColin Finck         case STATUS_BREAKPOINT:
673c2c66affSColin Finck         case STATUS_ACCESS_VIOLATION:
674c2c66affSColin Finck         case STATUS_ILLEGAL_INSTRUCTION:
675c2c66affSColin Finck         case STATUS_PRIVILEGED_INSTRUCTION:
676c2c66affSColin Finck         case STATUS_INSTRUCTION_MISALIGNMENT:
677c2c66affSColin Finck         case STATUS_STACK_OVERFLOW:
678c2c66affSColin Finck         case STATUS_POSSIBLE_DEADLOCK:
679f2f9161aSAmine Khaldi             ok(retval == EXCEPTION_CONTINUE_SEARCH, "%s(0x%x) should have returned %d instead of %d\n",
680f2f9161aSAmine Khaldi                func_name, exception, EXCEPTION_CONTINUE_SEARCH, retval);
681c2c66affSColin Finck             break;
682c2c66affSColin Finck         case STATUS_GUARD_PAGE_VIOLATION:
683c2c66affSColin Finck         case STATUS_IN_PAGE_ERROR:
684c2c66affSColin Finck         case STATUS_HANDLE_NOT_CLOSABLE:
685f2f9161aSAmine Khaldi             trace("%s(0x%x) returned %d\n", func_name, exception, retval);
686c2c66affSColin Finck             break;
687c2c66affSColin Finck         default:
688f2f9161aSAmine Khaldi             ok(retval == EXCEPTION_EXECUTE_HANDLER, "%s(0x%x) should have returned %d instead of %d\n",
689f2f9161aSAmine Khaldi                func_name, exception, EXCEPTION_EXECUTE_HANDLER, retval);
690c2c66affSColin Finck         }
691c2c66affSColin Finck     }
692c2c66affSColin Finck }
693c2c66affSColin Finck 
test_RpcStringBindingFromBinding(void)694c2c66affSColin Finck static void test_RpcStringBindingFromBinding(void)
695c2c66affSColin Finck {
696c2c66affSColin Finck     static unsigned char ncacn_np[] = "ncacn_np";
697c2c66affSColin Finck     static unsigned char address[] = ".";
698c2c66affSColin Finck     static unsigned char endpoint[] = "\\pipe\\wine_rpc_test";
699c2c66affSColin Finck     RPC_STATUS status;
700c2c66affSColin Finck     handle_t handle;
701c2c66affSColin Finck     RPC_CSTR binding;
702c2c66affSColin Finck 
703c2c66affSColin Finck     status = RpcStringBindingComposeA(NULL, ncacn_np, address,
704c2c66affSColin Finck                                      endpoint, NULL, &binding);
705c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingCompose failed (%u)\n", status);
706c2c66affSColin Finck 
707c2c66affSColin Finck     status = RpcBindingFromStringBindingA(binding, &handle);
708c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingFromStringBinding failed (%u)\n", status);
709c2c66affSColin Finck     RpcStringFreeA(&binding);
710c2c66affSColin Finck 
711c2c66affSColin Finck     status = RpcBindingToStringBindingA(handle, &binding);
712c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcStringBindingFromBinding failed with error %u\n", status);
713c2c66affSColin Finck 
714c2c66affSColin Finck     ok(!strcmp((const char *)binding, "ncacn_np:.[\\\\pipe\\\\wine_rpc_test]"),
715c2c66affSColin Finck        "binding string didn't match what was expected: \"%s\"\n", binding);
716c2c66affSColin Finck     RpcStringFreeA(&binding);
717c2c66affSColin Finck 
718c2c66affSColin Finck     status = RpcBindingFree(&handle);
719c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcBindingFree failed with error %u\n", status);
720c2c66affSColin Finck }
721c2c66affSColin Finck 
test_UuidCreate(void)722c2c66affSColin Finck static void test_UuidCreate(void)
723c2c66affSColin Finck {
724c2c66affSColin Finck     UUID guid;
725c2c66affSColin Finck     BYTE version;
726c2c66affSColin Finck 
727c2c66affSColin Finck     UuidCreate(&guid);
728c2c66affSColin Finck     version = (guid.Data3 & 0xf000) >> 12;
729c2c66affSColin Finck     ok(version == 4 || broken(version == 1), "unexpected version %d\n",
730c2c66affSColin Finck        version);
731c2c66affSColin Finck     if (version == 4)
732c2c66affSColin Finck     {
733c2c66affSColin Finck         static UUID v4and = { 0, 0, 0x4000, { 0x80,0,0,0,0,0,0,0 } };
734c2c66affSColin Finck         static UUID v4or = { 0xffffffff, 0xffff, 0x4fff,
735c2c66affSColin Finck            { 0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff } };
736c2c66affSColin Finck         UUID and, or;
737c2c66affSColin Finck         RPC_STATUS rslt;
738c2c66affSColin Finck         int i;
739c2c66affSColin Finck 
740c2c66affSColin Finck         and = guid;
741c2c66affSColin Finck         or = guid;
742c2c66affSColin Finck         /* Generate a bunch of UUIDs and mask them.  By the end, we expect
743c2c66affSColin Finck          * every randomly generated bit to have been zero at least once,
744c2c66affSColin Finck          * resulting in no bits set in the and mask except those which are not
745c2c66affSColin Finck          * randomly generated:  the version number and the topmost bits of the
746c2c66affSColin Finck          * Data4 field (treated as big-endian.)  Similarly, we expect only
747c2c66affSColin Finck          * the bits which are not randomly set to be cleared in the or mask.
748c2c66affSColin Finck          */
749c2c66affSColin Finck         for (i = 0; i < 1000; i++)
750c2c66affSColin Finck         {
751c2c66affSColin Finck             LPBYTE src, dst;
752c2c66affSColin Finck 
753c2c66affSColin Finck             UuidCreate(&guid);
754c2c66affSColin Finck             for (src = (LPBYTE)&guid, dst = (LPBYTE)&and;
755c2c66affSColin Finck              src - (LPBYTE)&guid < sizeof(guid); src++, dst++)
756c2c66affSColin Finck                 *dst &= *src;
757c2c66affSColin Finck             for (src = (LPBYTE)&guid, dst = (LPBYTE)&or;
758c2c66affSColin Finck              src - (LPBYTE)&guid < sizeof(guid); src++, dst++)
759c2c66affSColin Finck                 *dst |= *src;
760c2c66affSColin Finck         }
761c2c66affSColin Finck         ok(UuidEqual(&and, &v4and, &rslt),
762c2c66affSColin Finck            "unexpected bits set in V4 UUID: %s\n", wine_dbgstr_guid(&and));
763c2c66affSColin Finck         ok(UuidEqual(&or, &v4or, &rslt),
764c2c66affSColin Finck            "unexpected bits set in V4 UUID: %s\n", wine_dbgstr_guid(&or));
765c2c66affSColin Finck     }
766c2c66affSColin Finck     else
767c2c66affSColin Finck     {
768c2c66affSColin Finck         /* Older versions of Windows generate V1 UUIDs.  For these, there are
769c2c66affSColin Finck          * many stable bits, including at least the MAC address if one is
770c2c66affSColin Finck          * present.  Just check that Data4[0]'s most significant bits are
771c2c66affSColin Finck          * set as expected.
772c2c66affSColin Finck          */
773c2c66affSColin Finck         ok((guid.Data4[0] & 0xc0) == 0x80,
774c2c66affSColin Finck            "unexpected value in Data4[0]: %02x\n", guid.Data4[0] & 0xc0);
775c2c66affSColin Finck     }
776c2c66affSColin Finck }
777c2c66affSColin Finck 
test_UuidCreateSequential(void)778c2c66affSColin Finck static void test_UuidCreateSequential(void)
779c2c66affSColin Finck {
780c2c66affSColin Finck     UUID guid1;
781c2c66affSColin Finck     BYTE version;
782c2c66affSColin Finck     RPC_STATUS (WINAPI *pUuidCreateSequential)(UUID *) = (void *)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "UuidCreateSequential");
783c2c66affSColin Finck     RPC_STATUS (WINAPI *pI_UuidCreate)(UUID *) = (void*)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "I_UuidCreate");
784c2c66affSColin Finck     RPC_STATUS ret;
785c2c66affSColin Finck 
786c2c66affSColin Finck     if (!pUuidCreateSequential)
787c2c66affSColin Finck     {
788c2c66affSColin Finck         win_skip("UuidCreateSequential not exported\n");
789c2c66affSColin Finck         return;
790c2c66affSColin Finck     }
791c2c66affSColin Finck 
792c2c66affSColin Finck     ok(pI_UuidCreate != pUuidCreateSequential, "got %p, %p\n", pI_UuidCreate, pUuidCreateSequential);
793c2c66affSColin Finck 
794c2c66affSColin Finck     ret = pUuidCreateSequential(&guid1);
795c2c66affSColin Finck     ok(!ret || ret == RPC_S_UUID_LOCAL_ONLY,
796c2c66affSColin Finck        "expected RPC_S_OK or RPC_S_UUID_LOCAL_ONLY, got %08x\n", ret);
797c2c66affSColin Finck     version = (guid1.Data3 & 0xf000) >> 12;
798c2c66affSColin Finck     ok(version == 1, "unexpected version %d\n", version);
799c2c66affSColin Finck     if (version == 1)
800c2c66affSColin Finck     {
801c2c66affSColin Finck         UUID guid2;
802c2c66affSColin Finck 
803c2c66affSColin Finck         if (!ret)
804c2c66affSColin Finck         {
805c2c66affSColin Finck             /* If the call succeeded, there's a valid (non-multicast) MAC
806c2c66affSColin Finck              * address in the uuid:
807c2c66affSColin Finck              */
808c2c66affSColin Finck             ok(!(guid1.Data4[2] & 0x01) || broken(guid1.Data4[2] & 0x01), /* Win 8.1 */
809c2c66affSColin Finck                "GUID does not appear to contain a MAC address: %s\n",
810c2c66affSColin Finck                wine_dbgstr_guid(&guid1));
811c2c66affSColin Finck         }
812c2c66affSColin Finck         else
813c2c66affSColin Finck         {
814c2c66affSColin Finck             /* Otherwise, there's a randomly generated multicast MAC address
815c2c66affSColin Finck              * address in the uuid:
816c2c66affSColin Finck              */
817c2c66affSColin Finck             ok((guid1.Data4[2] & 0x01),
818c2c66affSColin Finck                "GUID does not appear to contain a multicast MAC address: %s\n",
819c2c66affSColin Finck                wine_dbgstr_guid(&guid1));
820c2c66affSColin Finck         }
821c2c66affSColin Finck         /* Generate another GUID, and make sure its MAC address matches the
822c2c66affSColin Finck          * first.
823c2c66affSColin Finck          */
824c2c66affSColin Finck         ret = pUuidCreateSequential(&guid2);
825c2c66affSColin Finck         ok(!ret || ret == RPC_S_UUID_LOCAL_ONLY,
826c2c66affSColin Finck            "expected RPC_S_OK or RPC_S_UUID_LOCAL_ONLY, got %08x\n", ret);
827c2c66affSColin Finck         version = (guid2.Data3 & 0xf000) >> 12;
828c2c66affSColin Finck         ok(version == 1, "unexpected version %d\n", version);
829c2c66affSColin Finck         ok(!memcmp(guid1.Data4, guid2.Data4, sizeof(guid2.Data4)),
830c2c66affSColin Finck            "unexpected value in MAC address: %s\n",
831c2c66affSColin Finck            wine_dbgstr_guid(&guid2));
832c2c66affSColin Finck 
833c2c66affSColin Finck         /* I_UuidCreate does exactly the same */
834c2c66affSColin Finck         pI_UuidCreate(&guid2);
835c2c66affSColin Finck         version = (guid2.Data3 & 0xf000) >> 12;
836c2c66affSColin Finck         ok(version == 1, "unexpected version %d\n", version);
837c2c66affSColin Finck         ok(!memcmp(guid1.Data4, guid2.Data4, sizeof(guid2.Data4)),
838c2c66affSColin Finck            "unexpected value in MAC address: %s\n",
839c2c66affSColin Finck            wine_dbgstr_guid(&guid2));
840c2c66affSColin Finck     }
841c2c66affSColin Finck }
842c2c66affSColin Finck 
test_RpcBindingFree(void)843c2c66affSColin Finck static void test_RpcBindingFree(void)
844c2c66affSColin Finck {
845c2c66affSColin Finck     RPC_BINDING_HANDLE binding = NULL;
846c2c66affSColin Finck     RPC_STATUS status;
847c2c66affSColin Finck 
848c2c66affSColin Finck     status = RpcBindingFree(&binding);
849c2c66affSColin Finck     ok(status == RPC_S_INVALID_BINDING,
850c2c66affSColin Finck        "RpcBindingFree should have returned RPC_S_INVALID_BINDING instead of %d\n",
851c2c66affSColin Finck        status);
852c2c66affSColin Finck }
853c2c66affSColin Finck 
test_RpcStringFree(void)854*2a783979SEric Kohl static void test_RpcStringFree(void)
855*2a783979SEric Kohl {
856*2a783979SEric Kohl     RPC_WSTR string = NULL;
857*2a783979SEric Kohl 
858*2a783979SEric Kohl     string = HeapAlloc(GetProcessHeap(), 0, 10*sizeof(WCHAR));
859*2a783979SEric Kohl     if (string == NULL)
860*2a783979SEric Kohl     {
861*2a783979SEric Kohl         skip("Failed to allocate a string!\n");
862*2a783979SEric Kohl         return;
863*2a783979SEric Kohl     }
864*2a783979SEric Kohl 
865*2a783979SEric Kohl     RpcStringFreeW(&string);
866*2a783979SEric Kohl 
867*2a783979SEric Kohl     ok(string == NULL, "String is %p expected NULL!\n", string);
868*2a783979SEric Kohl }
869*2a783979SEric Kohl 
test_RpcServerInqDefaultPrincName(void)870c2c66affSColin Finck static void test_RpcServerInqDefaultPrincName(void)
871c2c66affSColin Finck {
872c2c66affSColin Finck     RPC_STATUS ret;
873c2c66affSColin Finck     RPC_CSTR principal, saved_principal;
874c2c66affSColin Finck     char *username;
875c2c66affSColin Finck     ULONG len = 0;
876c2c66affSColin Finck 
877c2c66affSColin Finck     GetUserNameExA( NameSamCompatible, NULL, &len );
878c2c66affSColin Finck     username = HeapAlloc( GetProcessHeap(), 0, len );
879c2c66affSColin Finck     GetUserNameExA( NameSamCompatible, username, &len );
880c2c66affSColin Finck 
881c2c66affSColin Finck     ret = RpcServerInqDefaultPrincNameA( 0, NULL );
882c2c66affSColin Finck     ok( ret == RPC_S_UNKNOWN_AUTHN_SERVICE, "got %u\n", ret );
883c2c66affSColin Finck 
884c2c66affSColin Finck     ret = RpcServerInqDefaultPrincNameA( RPC_C_AUTHN_DEFAULT, NULL );
885c2c66affSColin Finck     ok( ret == RPC_S_UNKNOWN_AUTHN_SERVICE, "got %u\n", ret );
886c2c66affSColin Finck 
887c2c66affSColin Finck     principal = (RPC_CSTR)0xdeadbeef;
888c2c66affSColin Finck     ret = RpcServerInqDefaultPrincNameA( RPC_C_AUTHN_DEFAULT, &principal );
889c2c66affSColin Finck     ok( ret == RPC_S_UNKNOWN_AUTHN_SERVICE, "got %u\n", ret );
890c2c66affSColin Finck     ok( principal == (RPC_CSTR)0xdeadbeef, "got unexpected principal\n" );
891c2c66affSColin Finck 
892c2c66affSColin Finck     saved_principal = (RPC_CSTR)0xdeadbeef;
893c2c66affSColin Finck     ret = RpcServerInqDefaultPrincNameA( RPC_C_AUTHN_WINNT, &saved_principal );
894c2c66affSColin Finck     ok( ret == RPC_S_OK, "got %u\n", ret );
895c2c66affSColin Finck     ok( saved_principal != (RPC_CSTR)0xdeadbeef, "expected valid principal\n" );
896c2c66affSColin Finck     ok( !strcmp( (const char *)saved_principal, username ), "got \'%s\'\n", saved_principal );
897c2c66affSColin Finck     trace("%s\n", saved_principal);
898c2c66affSColin Finck 
899c2c66affSColin Finck     ret = RpcServerRegisterAuthInfoA( (RPC_CSTR)"wine\\test", RPC_C_AUTHN_WINNT, NULL, NULL );
900c2c66affSColin Finck     ok( ret == RPC_S_OK, "got %u\n", ret );
901c2c66affSColin Finck 
902c2c66affSColin Finck     principal = (RPC_CSTR)0xdeadbeef;
903c2c66affSColin Finck     ret = RpcServerInqDefaultPrincNameA( RPC_C_AUTHN_WINNT, &principal );
904c2c66affSColin Finck     ok( ret == RPC_S_OK, "got %u\n", ret );
905c2c66affSColin Finck     ok( principal != (RPC_CSTR)0xdeadbeef, "expected valid principal\n" );
906c2c66affSColin Finck     ok( !strcmp( (const char *)principal, username ), "got \'%s\'\n", principal );
907c2c66affSColin Finck     RpcStringFreeA( &principal );
908c2c66affSColin Finck 
909c2c66affSColin Finck     ret = RpcServerRegisterAuthInfoA( saved_principal, RPC_C_AUTHN_WINNT, NULL, NULL );
910c2c66affSColin Finck     ok( ret == RPC_S_OK, "got %u\n", ret );
911c2c66affSColin Finck 
912c2c66affSColin Finck     RpcStringFreeA( &saved_principal );
913c2c66affSColin Finck     HeapFree( GetProcessHeap(), 0, username );
914c2c66affSColin Finck }
915c2c66affSColin Finck 
test_RpcServerRegisterAuthInfo(void)916c2c66affSColin Finck static void test_RpcServerRegisterAuthInfo(void)
917c2c66affSColin Finck {
918c2c66affSColin Finck     RPC_STATUS status;
919c2c66affSColin Finck 
920c2c66affSColin Finck     status = RpcServerRegisterAuthInfoW(NULL, 600, NULL, NULL);
921c2c66affSColin Finck     ok(status == RPC_S_UNKNOWN_AUTHN_SERVICE, "status = %x\n", status);
922c2c66affSColin Finck }
923c2c66affSColin Finck 
test_RpcServerUseProtseq(void)924c2c66affSColin Finck static void test_RpcServerUseProtseq(void)
925c2c66affSColin Finck {
926c2c66affSColin Finck     RPC_STATUS status;
927c2c66affSColin Finck     RPC_BINDING_VECTOR *bindings;
928c2c66affSColin Finck     ULONG i;
929c2c66affSColin Finck     ULONG binding_count_before;
930c2c66affSColin Finck     ULONG binding_count_after1;
931c2c66affSColin Finck     ULONG binding_count_after2;
932c2c66affSColin Finck     ULONG endpoints_registered = 0;
933c2c66affSColin Finck     static unsigned char iptcp[] = "ncacn_ip_tcp";
934c2c66affSColin Finck     static unsigned char np[] = "ncacn_np";
935c2c66affSColin Finck     static unsigned char ncalrpc[] = "ncalrpc";
936c2c66affSColin Finck     BOOL iptcp_registered = FALSE, np_registered = FALSE, ncalrpc_registered = FALSE;
937c2c66affSColin Finck 
938c2c66affSColin Finck     status = RpcServerInqBindings(&bindings);
939c2c66affSColin Finck     if (status == RPC_S_NO_BINDINGS)
940c2c66affSColin Finck         binding_count_before = 0;
941c2c66affSColin Finck     else
942c2c66affSColin Finck     {
943c2c66affSColin Finck         binding_count_before = bindings->Count;
944c2c66affSColin Finck         ok(status == RPC_S_OK, "RpcServerInqBindings failed with status %d\n", status);
945c2c66affSColin Finck         for (i = 0; i < bindings->Count; i++)
946c2c66affSColin Finck         {
947c2c66affSColin Finck             RPC_CSTR str_bind;
948c2c66affSColin Finck             status = RpcBindingToStringBindingA(bindings->BindingH[i], &str_bind);
949c2c66affSColin Finck             ok(status == RPC_S_OK, "RpcBindingToStringBinding failed with status %d\n", status);
950c2c66affSColin Finck             if (lstrlenA((const char *)str_bind) > 12 && !memcmp(str_bind, "ncacn_ip_tcp", 12))
951c2c66affSColin Finck                 iptcp_registered = TRUE;
952c2c66affSColin Finck             if (lstrlenA((const char *)str_bind) > 8 && !memcmp(str_bind, "ncacn_np", 8))
953c2c66affSColin Finck                 np_registered = TRUE;
954c2c66affSColin Finck             if (lstrlenA((const char *)str_bind) > 7 && !memcmp(str_bind, "ncalrpc", 7))
955c2c66affSColin Finck                 ncalrpc_registered = TRUE;
956c2c66affSColin Finck             RpcStringFreeA(&str_bind);
957c2c66affSColin Finck         }
958c2c66affSColin Finck         RpcBindingVectorFree(&bindings);
959c2c66affSColin Finck     }
960c2c66affSColin Finck 
961c2c66affSColin Finck     /* show that RpcServerUseProtseqEp(..., NULL, ...) is the same as
962c2c66affSColin Finck      * RpcServerUseProtseq(...) */
963c2c66affSColin Finck     status = RpcServerUseProtseqEpA(ncalrpc, 0, NULL, NULL);
964c2c66affSColin Finck     ok(status == RPC_S_OK || broken(status == RPC_S_INVALID_ENDPOINT_FORMAT),
965c2c66affSColin Finck        "RpcServerUseProtseqEp with NULL endpoint failed with status %d\n",
966c2c66affSColin Finck        status);
967c2c66affSColin Finck 
968c2c66affSColin Finck     /* register protocol sequences without explicit endpoints */
969c2c66affSColin Finck     status = RpcServerUseProtseqA(np, 0, NULL);
970c2c66affSColin Finck     if (status == RPC_S_PROTSEQ_NOT_SUPPORTED)
971c2c66affSColin Finck         win_skip("ncacn_np not supported\n");
972c2c66affSColin Finck     else
973c2c66affSColin Finck         ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_np) failed with status %d\n", status);
974c2c66affSColin Finck     if (status == RPC_S_OK && !np_registered) endpoints_registered++;
975c2c66affSColin Finck 
976c2c66affSColin Finck     status = RpcServerUseProtseqA(iptcp, 0, NULL);
977c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_ip_tcp) failed with status %d\n", status);
978c2c66affSColin Finck     if (status == RPC_S_OK && !iptcp_registered) endpoints_registered++;
979c2c66affSColin Finck 
980c2c66affSColin Finck     status = RpcServerUseProtseqA(ncalrpc, 0, NULL);
981c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", status);
982c2c66affSColin Finck     if (status == RPC_S_OK && !ncalrpc_registered) endpoints_registered++;
983c2c66affSColin Finck 
984c2c66affSColin Finck     status = RpcServerInqBindings(&bindings);
985c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerInqBindings failed with status %d\n", status);
986c2c66affSColin Finck     binding_count_after1 = bindings->Count;
987c2c66affSColin Finck     ok(binding_count_after1 == binding_count_before + endpoints_registered,
988c2c66affSColin Finck        "wrong binding count - before: %u, after %u, endpoints registered %u\n",
989c2c66affSColin Finck        binding_count_before, binding_count_after1, endpoints_registered);
990c2c66affSColin Finck     for (i = 0; i < bindings->Count; i++)
991c2c66affSColin Finck     {
992c2c66affSColin Finck         RPC_CSTR str_bind;
993c2c66affSColin Finck         status = RpcBindingToStringBindingA(bindings->BindingH[i], &str_bind);
994c2c66affSColin Finck         ok(status == RPC_S_OK, "RpcBindingToStringBinding failed with status %d\n", status);
995c2c66affSColin Finck         trace("string binding: %s\n", str_bind);
996c2c66affSColin Finck         RpcStringFreeA(&str_bind);
997c2c66affSColin Finck     }
998c2c66affSColin Finck     RpcBindingVectorFree(&bindings);
999c2c66affSColin Finck 
1000c2c66affSColin Finck     /* re-register - endpoints should be reused */
1001c2c66affSColin Finck     status = RpcServerUseProtseqA(np, 0, NULL);
1002c2c66affSColin Finck     if (status == RPC_S_PROTSEQ_NOT_SUPPORTED)
1003c2c66affSColin Finck         win_skip("ncacn_np not supported\n");
1004c2c66affSColin Finck     else
1005c2c66affSColin Finck         ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_np) failed with status %d\n", status);
1006c2c66affSColin Finck 
1007c2c66affSColin Finck     status = RpcServerUseProtseqA(iptcp, 0, NULL);
1008c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_ip_tcp) failed with status %d\n", status);
1009c2c66affSColin Finck 
1010c2c66affSColin Finck     status = RpcServerUseProtseqA(ncalrpc, 0, NULL);
1011c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", status);
1012c2c66affSColin Finck 
1013c2c66affSColin Finck     status = RpcServerInqBindings(&bindings);
1014c2c66affSColin Finck     ok(status == RPC_S_OK, "RpcServerInqBindings failed with status %d\n", status);
1015c2c66affSColin Finck     binding_count_after2 = bindings->Count;
1016c2c66affSColin Finck     ok(binding_count_after2 == binding_count_after1,
1017c2c66affSColin Finck        "bindings should have been re-used - after1: %u after2: %u\n",
1018c2c66affSColin Finck        binding_count_after1, binding_count_after2);
1019c2c66affSColin Finck     RpcBindingVectorFree(&bindings);
1020c2c66affSColin Finck }
1021c2c66affSColin Finck 
test_endpoint_mapper(RPC_CSTR protseq,RPC_CSTR address)1022c2c66affSColin Finck static void test_endpoint_mapper(RPC_CSTR protseq, RPC_CSTR address)
1023c2c66affSColin Finck {
1024c2c66affSColin Finck     static unsigned char annotation[] = "Test annotation string.";
1025c2c66affSColin Finck     RPC_STATUS status;
1026c2c66affSColin Finck     RPC_BINDING_VECTOR *binding_vector;
1027c2c66affSColin Finck     handle_t handle;
1028c2c66affSColin Finck     unsigned char *binding;
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     status = RpcServerRegisterIf(IFoo_v0_0_s_ifspec, NULL, NULL);
1031c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcServerRegisterIf failed (%u)\n", protseq, status);
1032c2c66affSColin Finck 
1033c2c66affSColin Finck     status = RpcServerInqBindings(&binding_vector);
1034c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcServerInqBindings failed with error %u\n", protseq, status);
1035c2c66affSColin Finck 
1036c2c66affSColin Finck     /* register endpoints created in test_RpcServerUseProtseq */
1037c2c66affSColin Finck     status = RpcEpRegisterA(IFoo_v0_0_s_ifspec, binding_vector, NULL, annotation);
1038c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcEpRegisterA failed with error %u\n", protseq, status);
1039c2c66affSColin Finck     /* reregister the same endpoint with no annotation */
1040c2c66affSColin Finck     status = RpcEpRegisterA(IFoo_v0_0_s_ifspec, binding_vector, NULL, NULL);
1041c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcEpRegisterA failed with error %u\n", protseq, status);
1042c2c66affSColin Finck 
1043c2c66affSColin Finck     status = RpcStringBindingComposeA(NULL, protseq, address,
1044c2c66affSColin Finck                                      NULL, NULL, &binding);
1045c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcStringBindingCompose failed (%u)\n", protseq, status);
1046c2c66affSColin Finck 
1047c2c66affSColin Finck     status = RpcBindingFromStringBindingA(binding, &handle);
1048c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcBindingFromStringBinding failed (%u)\n", protseq, status);
1049c2c66affSColin Finck 
1050c2c66affSColin Finck     RpcStringFreeA(&binding);
1051c2c66affSColin Finck 
1052c2c66affSColin Finck     status = RpcBindingReset(handle);
1053c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %u\n", protseq, status);
1054c2c66affSColin Finck 
1055c2c66affSColin Finck     status = RpcEpResolveBinding(handle, IFoo_v0_0_s_ifspec);
1056c2c66affSColin Finck     ok(status == RPC_S_OK || broken(status == RPC_S_SERVER_UNAVAILABLE), /* win9x */
1057c2c66affSColin Finck        "%s: RpcEpResolveBinding failed with error %u\n", protseq, status);
1058c2c66affSColin Finck 
1059c2c66affSColin Finck     status = RpcBindingReset(handle);
1060c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %u\n", protseq, status);
1061c2c66affSColin Finck 
1062c2c66affSColin Finck     status = RpcBindingFree(&handle);
1063c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcBindingFree failed with error %u\n", protseq, status);
1064c2c66affSColin Finck 
1065c2c66affSColin Finck     status = RpcServerUnregisterIf(NULL, NULL, FALSE);
1066c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcServerUnregisterIf failed (%u)\n", protseq, status);
1067c2c66affSColin Finck 
1068c2c66affSColin Finck     status = RpcEpUnregister(IFoo_v0_0_s_ifspec, binding_vector, NULL);
1069c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcEpUnregisterA failed with error %u\n", protseq, status);
1070c2c66affSColin Finck 
1071c2c66affSColin Finck     status = RpcBindingVectorFree(&binding_vector);
1072c2c66affSColin Finck     ok(status == RPC_S_OK, "%s: RpcBindingVectorFree failed with error %u\n", protseq, status);
1073c2c66affSColin Finck }
1074c2c66affSColin Finck 
is_process_elevated(void)1075c2c66affSColin Finck static BOOL is_process_elevated(void)
1076c2c66affSColin Finck {
1077c2c66affSColin Finck     HANDLE token;
1078c2c66affSColin Finck     if (OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ))
1079c2c66affSColin Finck     {
1080c2c66affSColin Finck         TOKEN_ELEVATION_TYPE type;
1081c2c66affSColin Finck         DWORD size;
1082c2c66affSColin Finck         BOOL ret;
1083c2c66affSColin Finck 
1084c2c66affSColin Finck         ret = GetTokenInformation( token, TokenElevationType, &type, sizeof(type), &size );
1085c2c66affSColin Finck         CloseHandle( token );
1086c2c66affSColin Finck         return (ret && type == TokenElevationTypeFull);
1087c2c66affSColin Finck     }
1088c2c66affSColin Finck     return FALSE;
1089c2c66affSColin Finck }
1090c2c66affSColin Finck 
is_firewall_enabled(void)1091c2c66affSColin Finck static BOOL is_firewall_enabled(void)
1092c2c66affSColin Finck {
1093c2c66affSColin Finck     HRESULT hr, init;
1094c2c66affSColin Finck     INetFwMgr *mgr = NULL;
1095c2c66affSColin Finck     INetFwPolicy *policy = NULL;
1096c2c66affSColin Finck     INetFwProfile *profile = NULL;
1097c2c66affSColin Finck     VARIANT_BOOL enabled = VARIANT_FALSE;
1098c2c66affSColin Finck 
1099c2c66affSColin Finck     init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
1100c2c66affSColin Finck 
1101c2c66affSColin Finck     hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr,
1102c2c66affSColin Finck                            (void **)&mgr );
1103c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1104c2c66affSColin Finck     if (hr != S_OK) goto done;
1105c2c66affSColin Finck 
1106c2c66affSColin Finck     hr = INetFwMgr_get_LocalPolicy( mgr, &policy );
1107c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1108c2c66affSColin Finck     if (hr != S_OK) goto done;
1109c2c66affSColin Finck 
1110c2c66affSColin Finck     hr = INetFwPolicy_get_CurrentProfile( policy, &profile );
1111c2c66affSColin Finck     if (hr != S_OK) goto done;
1112c2c66affSColin Finck 
1113c2c66affSColin Finck     hr = INetFwProfile_get_FirewallEnabled( profile, &enabled );
1114c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1115c2c66affSColin Finck 
1116c2c66affSColin Finck done:
1117c2c66affSColin Finck     if (policy) INetFwPolicy_Release( policy );
1118c2c66affSColin Finck     if (profile) INetFwProfile_Release( profile );
1119c2c66affSColin Finck     if (mgr) INetFwMgr_Release( mgr );
1120c2c66affSColin Finck     if (SUCCEEDED( init )) CoUninitialize();
1121c2c66affSColin Finck     return (enabled == VARIANT_TRUE);
1122c2c66affSColin Finck }
1123c2c66affSColin Finck 
1124c2c66affSColin Finck enum firewall_op
1125c2c66affSColin Finck {
1126c2c66affSColin Finck     APP_ADD,
1127c2c66affSColin Finck     APP_REMOVE
1128c2c66affSColin Finck };
1129c2c66affSColin Finck 
set_firewall(enum firewall_op op)1130c2c66affSColin Finck static HRESULT set_firewall( enum firewall_op op )
1131c2c66affSColin Finck {
1132c2c66affSColin Finck     static const WCHAR testW[] = {'r','p','c','r','t','4','_','t','e','s','t',0};
1133c2c66affSColin Finck     HRESULT hr, init;
1134c2c66affSColin Finck     INetFwMgr *mgr = NULL;
1135c2c66affSColin Finck     INetFwPolicy *policy = NULL;
1136c2c66affSColin Finck     INetFwProfile *profile = NULL;
1137c2c66affSColin Finck     INetFwAuthorizedApplication *app = NULL;
1138c2c66affSColin Finck     INetFwAuthorizedApplications *apps = NULL;
1139c2c66affSColin Finck     BSTR name, image = SysAllocStringLen( NULL, MAX_PATH );
1140c2c66affSColin Finck 
1141c2c66affSColin Finck     if (!GetModuleFileNameW( NULL, image, MAX_PATH ))
1142c2c66affSColin Finck     {
1143c2c66affSColin Finck         SysFreeString( image );
1144c2c66affSColin Finck         return E_FAIL;
1145c2c66affSColin Finck     }
1146c2c66affSColin Finck     init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
1147c2c66affSColin Finck 
1148c2c66affSColin Finck     hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr,
1149c2c66affSColin Finck                            (void **)&mgr );
1150c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1151c2c66affSColin Finck     if (hr != S_OK) goto done;
1152c2c66affSColin Finck 
1153c2c66affSColin Finck     hr = INetFwMgr_get_LocalPolicy( mgr, &policy );
1154c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1155c2c66affSColin Finck     if (hr != S_OK) goto done;
1156c2c66affSColin Finck 
1157c2c66affSColin Finck     hr = INetFwPolicy_get_CurrentProfile( policy, &profile );
1158c2c66affSColin Finck     if (hr != S_OK) goto done;
1159c2c66affSColin Finck 
1160c2c66affSColin Finck     hr = INetFwProfile_get_AuthorizedApplications( profile, &apps );
1161c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1162c2c66affSColin Finck     if (hr != S_OK) goto done;
1163c2c66affSColin Finck 
1164c2c66affSColin Finck     hr = CoCreateInstance( &CLSID_NetFwAuthorizedApplication, NULL, CLSCTX_INPROC_SERVER,
1165c2c66affSColin Finck                            &IID_INetFwAuthorizedApplication, (void **)&app );
1166c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1167c2c66affSColin Finck     if (hr != S_OK) goto done;
1168c2c66affSColin Finck 
1169c2c66affSColin Finck     hr = INetFwAuthorizedApplication_put_ProcessImageFileName( app, image );
1170c2c66affSColin Finck     if (hr != S_OK) goto done;
1171c2c66affSColin Finck 
1172c2c66affSColin Finck     name = SysAllocString( testW );
1173c2c66affSColin Finck     hr = INetFwAuthorizedApplication_put_Name( app, name );
1174c2c66affSColin Finck     SysFreeString( name );
1175c2c66affSColin Finck     ok( hr == S_OK, "got %08x\n", hr );
1176c2c66affSColin Finck     if (hr != S_OK) goto done;
1177c2c66affSColin Finck 
1178c2c66affSColin Finck     if (op == APP_ADD)
1179c2c66affSColin Finck         hr = INetFwAuthorizedApplications_Add( apps, app );
1180c2c66affSColin Finck     else if (op == APP_REMOVE)
1181c2c66affSColin Finck         hr = INetFwAuthorizedApplications_Remove( apps, image );
1182c2c66affSColin Finck     else
1183c2c66affSColin Finck         hr = E_INVALIDARG;
1184c2c66affSColin Finck 
1185c2c66affSColin Finck done:
1186c2c66affSColin Finck     if (app) INetFwAuthorizedApplication_Release( app );
1187c2c66affSColin Finck     if (apps) INetFwAuthorizedApplications_Release( apps );
1188c2c66affSColin Finck     if (policy) INetFwPolicy_Release( policy );
1189c2c66affSColin Finck     if (profile) INetFwProfile_Release( profile );
1190c2c66affSColin Finck     if (mgr) INetFwMgr_Release( mgr );
1191c2c66affSColin Finck     if (SUCCEEDED( init )) CoUninitialize();
1192c2c66affSColin Finck     SysFreeString( image );
1193c2c66affSColin Finck     return hr;
1194c2c66affSColin Finck }
1195c2c66affSColin Finck 
START_TEST(rpc)1196c2c66affSColin Finck START_TEST( rpc )
1197c2c66affSColin Finck {
1198c2c66affSColin Finck     static unsigned char ncacn_np[] = "ncacn_np";
1199c2c66affSColin Finck     static unsigned char ncalrpc[] = "ncalrpc";
1200c2c66affSColin Finck     static unsigned char np_address[] = ".";
1201c2c66affSColin Finck     BOOL firewall_enabled = is_firewall_enabled();
1202c2c66affSColin Finck 
1203c2c66affSColin Finck     if (firewall_enabled && !is_process_elevated())
1204c2c66affSColin Finck     {
1205c2c66affSColin Finck         skip("no privileges, skipping tests to avoid firewall dialog\n");
1206c2c66affSColin Finck         return;
1207c2c66affSColin Finck     }
1208c2c66affSColin Finck 
1209c2c66affSColin Finck     UuidConversionAndComparison();
1210c2c66affSColin Finck     TestDceErrorInqText();
1211c2c66affSColin Finck     test_towers();
1212c2c66affSColin Finck     test_I_RpcMapWin32Status();
1213c2c66affSColin Finck     test_RpcStringBindingParseA();
1214f2f9161aSAmine Khaldi     test_RpcExceptionFilter("I_RpcExceptionFilter");
1215f2f9161aSAmine Khaldi     test_RpcExceptionFilter("RpcExceptionFilter");
1216c2c66affSColin Finck     test_RpcStringBindingFromBinding();
1217c2c66affSColin Finck     test_UuidCreate();
1218c2c66affSColin Finck     test_UuidCreateSequential();
1219c2c66affSColin Finck     test_RpcBindingFree();
1220*2a783979SEric Kohl     test_RpcStringFree();
1221c2c66affSColin Finck     test_RpcServerInqDefaultPrincName();
1222c2c66affSColin Finck     test_RpcServerRegisterAuthInfo();
1223c2c66affSColin Finck 
1224c2c66affSColin Finck     if (firewall_enabled)
1225c2c66affSColin Finck     {
1226c2c66affSColin Finck         HRESULT hr = set_firewall(APP_ADD);
1227c2c66affSColin Finck         if (hr != S_OK)
1228c2c66affSColin Finck         {
1229c2c66affSColin Finck             skip("can't authorize app in firewall %08x\n", hr);
1230c2c66affSColin Finck             return;
1231c2c66affSColin Finck         }
1232c2c66affSColin Finck     }
1233c2c66affSColin Finck 
1234c2c66affSColin Finck     test_rpc_ncacn_ip_tcp();
1235c2c66affSColin Finck     test_RpcServerUseProtseq();
1236c2c66affSColin Finck     test_endpoint_mapper(ncacn_np, np_address);
1237c2c66affSColin Finck     test_endpoint_mapper(ncalrpc, NULL);
1238c2c66affSColin Finck 
1239c2c66affSColin Finck     if (firewall_enabled) set_firewall(APP_REMOVE);
1240c2c66affSColin Finck }
1241