1 /* DirectPlay Conformance Tests
2 *
3 * Copyright 2007 - Alessandro Pignotti
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include "wine/test.h"
21 #include <stdio.h>
22 #define INITGUID
23 #include <dplay.h>
24 #include <dplobby.h>
25
26
27 #define check(expected, result) \
28 ok( (expected) == (result), \
29 "expected=%d got=%d\n", \
30 (int)(expected), (int)(result) );
31 #define checkLP(expected, result) \
32 ok( (expected) == (result), \
33 "expected=%p got=%p\n", \
34 expected, result );
35 #define checkHR(expected, result) \
36 ok( (expected) == (result), \
37 "expected=%s got=%s\n", \
38 dpResult2str(expected), dpResult2str(result) );
39 #define checkStr(expected, result) \
40 ok( (result != NULL) && (!strcmp(expected, result)), \
41 "expected=%s got=%s\n", \
42 expected, result );
43 #define checkFlags(expected, result, flags) \
44 ok( (expected) == (result), \
45 "expected=0x%08x(%s) got=0x%08x(%s)\n", \
46 expected, dwFlags2str(expected, flags), \
47 result, dwFlags2str(result, flags) );
48 #define checkGuid(expected, result) \
49 ok( IsEqualGUID(expected, result), \
50 "expected=%s got=%s\n", \
51 Guid2str(expected), Guid2str(result) );
52 #define checkConv(expected, result, function) \
53 ok( (expected) == (result), \
54 "expected=0x%08x(%s) got=0x%08x(%s)\n", \
55 expected, function(expected), \
56 result, function(result) );
57
58
59 DEFINE_GUID(appGuid, 0xbdcfe03e, 0xf0ec, 0x415b, 0x82, 0x11, 0x6f, 0x86, 0xd8, 0x19, 0x7f, 0xe1);
60 DEFINE_GUID(appGuid2, 0x93417d3f, 0x7d26, 0x46ba, 0xb5, 0x76, 0xfe, 0x4b, 0x20, 0xbb, 0xad, 0x70);
61 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
62
63
64 typedef struct tagCallbackData
65 {
66 LPDIRECTPLAY4 pDP;
67 UINT dwCounter1, dwCounter2;
68 DWORD dwFlags;
69 char szTrace1[1024], szTrace2[1024];
70 DPID *dpid;
71 UINT dpidSize;
72 } CallbackData, *lpCallbackData;
73
74
75 static LPSTR get_temp_buffer(void)
76 {
77 static UINT index = 0;
78 static char buff[10][256];
79
80 index = (index + 1) % 10;
81 *buff[index] = 0;
82
83 return buff[index];
84 }
85
86
87 static LPCSTR Guid2str(const GUID *guid)
88 {
89 LPSTR buffer = get_temp_buffer();
90
91 if (!guid) return "(null)";
92
93 /* Service providers */
94 if (IsEqualGUID(guid, &DPSPGUID_IPX))
95 return "DPSPGUID_IPX";
96 if (IsEqualGUID(guid, &DPSPGUID_TCPIP))
97 return "DPSPGUID_TCPIP";
98 if (IsEqualGUID(guid, &DPSPGUID_SERIAL))
99 return "DPSPGUID_SERIAL";
100 if (IsEqualGUID(guid, &DPSPGUID_MODEM))
101 return "DPSPGUID_MODEM";
102 /* DirectPlay Address ID's */
103 if (IsEqualGUID(guid, &DPAID_TotalSize))
104 return "DPAID_TotalSize";
105 if (IsEqualGUID(guid, &DPAID_ServiceProvider))
106 return "DPAID_ServiceProvider";
107 if (IsEqualGUID(guid, &DPAID_LobbyProvider))
108 return "DPAID_LobbyProvider";
109 if (IsEqualGUID(guid, &DPAID_Phone))
110 return "DPAID_Phone";
111 if (IsEqualGUID(guid, &DPAID_PhoneW))
112 return "DPAID_PhoneW";
113 if (IsEqualGUID(guid, &DPAID_Modem))
114 return "DPAID_Modem";
115 if (IsEqualGUID(guid, &DPAID_ModemW))
116 return "DPAID_ModemW";
117 if (IsEqualGUID(guid, &DPAID_INet))
118 return "DPAID_INet";
119 if (IsEqualGUID(guid, &DPAID_INetW))
120 return "DPAID_INetW";
121 if (IsEqualGUID(guid, &DPAID_INetPort))
122 return "DPAID_INetPort";
123 if (IsEqualGUID(guid, &DPAID_ComPort))
124 return "DPAID_ComPort";
125
126 sprintf( buffer, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
127 guid->Data1, guid->Data2, guid->Data3,
128 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
129 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
130 return buffer;
131
132 }
133
134
135 static LPCSTR dpResult2str(HRESULT hr)
136 {
137 switch (hr)
138 {
139 case DP_OK: return "DP_OK";
140 case DPERR_ALREADYINITIALIZED: return "DPERR_ALREADYINITIALIZED";
141 case DPERR_ACCESSDENIED: return "DPERR_ACCESSDENIED";
142 case DPERR_ACTIVEPLAYERS: return "DPERR_ACTIVEPLAYERS";
143 case DPERR_BUFFERTOOSMALL: return "DPERR_BUFFERTOOSMALL";
144 case DPERR_CANTADDPLAYER: return "DPERR_CANTADDPLAYER";
145 case DPERR_CANTCREATEGROUP: return "DPERR_CANTCREATEGROUP";
146 case DPERR_CANTCREATEPLAYER: return "DPERR_CANTCREATEPLAYER";
147 case DPERR_CANTCREATESESSION: return "DPERR_CANTCREATESESSION";
148 case DPERR_CAPSNOTAVAILABLEYET: return "DPERR_CAPSNOTAVAILABLEYET";
149 case DPERR_EXCEPTION: return "DPERR_EXCEPTION";
150 case DPERR_GENERIC: return "DPERR_GENERIC";
151 case DPERR_INVALIDFLAGS: return "DPERR_INVALIDFLAGS";
152 case DPERR_INVALIDOBJECT: return "DPERR_INVALIDOBJECT";
153 case DPERR_INVALIDPARAMS: return "DPERR_INVALIDPARAMS";
154 /* symbol with the same value: DPERR_INVALIDPARAM */
155 case DPERR_INVALIDPLAYER: return "DPERR_INVALIDPLAYER";
156 case DPERR_INVALIDGROUP: return "DPERR_INVALIDGROUP";
157 case DPERR_NOCAPS: return "DPERR_NOCAPS";
158 case DPERR_NOCONNECTION: return "DPERR_NOCONNECTION";
159 case DPERR_NOMEMORY: return "DPERR_NOMEMORY";
160 /* symbol with the same value: DPERR_OUTOFMEMORY */
161 case DPERR_NOMESSAGES: return "DPERR_NOMESSAGES";
162 case DPERR_NONAMESERVERFOUND: return "DPERR_NONAMESERVERFOUND";
163 case DPERR_NOPLAYERS: return "DPERR_NOPLAYERS";
164 case DPERR_NOSESSIONS: return "DPERR_NOSESSIONS";
165 case DPERR_PENDING: return "DPERR_PENDING";
166 case DPERR_SENDTOOBIG: return "DPERR_SENDTOOBIG";
167 case DPERR_TIMEOUT: return "DPERR_TIMEOUT";
168 case DPERR_UNAVAILABLE: return "DPERR_UNAVAILABLE";
169 case DPERR_UNSUPPORTED: return "DPERR_UNSUPPORTED";
170 case DPERR_BUSY: return "DPERR_BUSY";
171 case DPERR_USERCANCEL: return "DPERR_USERCANCEL";
172 case DPERR_NOINTERFACE: return "DPERR_NOINTERFACE";
173 case DPERR_CANNOTCREATESERVER: return "DPERR_CANNOTCREATESERVER";
174 case DPERR_PLAYERLOST: return "DPERR_PLAYERLOST";
175 case DPERR_SESSIONLOST: return "DPERR_SESSIONLOST";
176 case DPERR_UNINITIALIZED: return "DPERR_UNINITIALIZED";
177 case DPERR_NONEWPLAYERS: return "DPERR_NONEWPLAYERS";
178 case DPERR_INVALIDPASSWORD: return "DPERR_INVALIDPASSWORD";
179 case DPERR_CONNECTING: return "DPERR_CONNECTING";
180 case DPERR_CONNECTIONLOST: return "DPERR_CONNECTIONLOST";
181 case DPERR_UNKNOWNMESSAGE: return "DPERR_UNKNOWNMESSAGE";
182 case DPERR_CANCELFAILED: return "DPERR_CANCELFAILED";
183 case DPERR_INVALIDPRIORITY: return "DPERR_INVALIDPRIORITY";
184 case DPERR_NOTHANDLED: return "DPERR_NOTHANDLED";
185 case DPERR_CANCELLED: return "DPERR_CANCELLED";
186 case DPERR_ABORTED: return "DPERR_ABORTED";
187 case DPERR_BUFFERTOOLARGE: return "DPERR_BUFFERTOOLARGE";
188 case DPERR_CANTCREATEPROCESS: return "DPERR_CANTCREATEPROCESS";
189 case DPERR_APPNOTSTARTED: return "DPERR_APPNOTSTARTED";
190 case DPERR_INVALIDINTERFACE: return "DPERR_INVALIDINTERFACE";
191 case DPERR_NOSERVICEPROVIDER: return "DPERR_NOSERVICEPROVIDER";
192 case DPERR_UNKNOWNAPPLICATION: return "DPERR_UNKNOWNAPPLICATION";
193 case DPERR_NOTLOBBIED: return "DPERR_NOTLOBBIED";
194 case DPERR_SERVICEPROVIDERLOADED: return "DPERR_SERVICEPROVIDERLOADED";
195 case DPERR_ALREADYREGISTERED: return "DPERR_ALREADYREGISTERED";
196 case DPERR_NOTREGISTERED: return "DPERR_NOTREGISTERED";
197 case DPERR_AUTHENTICATIONFAILED: return "DPERR_AUTHENTICATIONFAILED";
198 case DPERR_CANTLOADSSPI: return "DPERR_CANTLOADSSPI";
199 case DPERR_ENCRYPTIONFAILED: return "DPERR_ENCRYPTIONFAILED";
200 case DPERR_SIGNFAILED: return "DPERR_SIGNFAILED";
201 case DPERR_CANTLOADSECURITYPACKAGE: return "DPERR_CANTLOADSECURITYPACKAGE";
202 case DPERR_ENCRYPTIONNOTSUPPORTED: return "DPERR_ENCRYPTIONNOTSUPPORTED";
203 case DPERR_CANTLOADCAPI: return "DPERR_CANTLOADCAPI";
204 case DPERR_NOTLOGGEDIN: return "DPERR_NOTLOGGEDIN";
205 case DPERR_LOGONDENIED: return "DPERR_LOGONDENIED";
206 case CLASS_E_NOAGGREGATION: return "CLASS_E_NOAGGREGATION";
207
208 default:
209 {
210 LPSTR buffer = get_temp_buffer();
211 sprintf( buffer, "%d", HRESULT_CODE(hr) );
212 return buffer;
213 }
214 }
215 }
216
217 static LPCSTR dpMsgType2str(DWORD dwType)
218 {
219 switch(dwType)
220 {
221 case DPSYS_CREATEPLAYERORGROUP: return "DPSYS_CREATEPLAYERORGROUP";
222 case DPSYS_DESTROYPLAYERORGROUP: return "DPSYS_DESTROYPLAYERORGROUP";
223 case DPSYS_ADDPLAYERTOGROUP: return "DPSYS_ADDPLAYERTOGROUP";
224 case DPSYS_DELETEPLAYERFROMGROUP: return "DPSYS_DELETEPLAYERFROMGROUP";
225 case DPSYS_SESSIONLOST: return "DPSYS_SESSIONLOST";
226 case DPSYS_HOST: return "DPSYS_HOST";
227 case DPSYS_SETPLAYERORGROUPDATA: return "DPSYS_SETPLAYERORGROUPDATA";
228 case DPSYS_SETPLAYERORGROUPNAME: return "DPSYS_SETPLAYERORGROUPNAME";
229 case DPSYS_SETSESSIONDESC: return "DPSYS_SETSESSIONDESC";
230 case DPSYS_ADDGROUPTOGROUP: return "DPSYS_ADDGROUPTOGROUP";
231 case DPSYS_DELETEGROUPFROMGROUP: return "DPSYS_DELETEGROUPFROMGROUP";
232 case DPSYS_SECUREMESSAGE: return "DPSYS_SECUREMESSAGE";
233 case DPSYS_STARTSESSION: return "DPSYS_STARTSESSION";
234 case DPSYS_CHAT: return "DPSYS_DPSYS_CHAT";
235 case DPSYS_SETGROUPOWNER: return "DPSYS_SETGROUPOWNER";
236 case DPSYS_SENDCOMPLETE: return "DPSYS_SENDCOMPLETE";
237
238 default: return "UNKNOWN";
239 }
240 }
241
242 static LPCSTR dwFlags2str(DWORD dwFlags, DWORD flagType)
243 {
244
245 #define FLAGS_DPCONNECTION (1<<0)
246 #define FLAGS_DPENUMPLAYERS (1<<1)
247 #define FLAGS_DPENUMGROUPS (1<<2)
248 #define FLAGS_DPPLAYER (1<<3)
249 #define FLAGS_DPGROUP (1<<4)
250 #define FLAGS_DPENUMSESSIONS (1<<5)
251 #define FLAGS_DPGETCAPS (1<<6)
252 #define FLAGS_DPGET (1<<7)
253 #define FLAGS_DPRECEIVE (1<<8)
254 #define FLAGS_DPSEND (1<<9)
255 #define FLAGS_DPSET (1<<10)
256 #define FLAGS_DPMESSAGEQUEUE (1<<11)
257 #define FLAGS_DPCONNECT (1<<12)
258 #define FLAGS_DPOPEN (1<<13)
259 #define FLAGS_DPSESSION (1<<14)
260 #define FLAGS_DPLCONNECTION (1<<15)
261 #define FLAGS_DPESC (1<<16)
262 #define FLAGS_DPCAPS (1<<17)
263
264 LPSTR flags = get_temp_buffer();
265
266 /* EnumConnections */
267
268 if (flagType & FLAGS_DPCONNECTION)
269 {
270 if (dwFlags & DPCONNECTION_DIRECTPLAY)
271 strcat(flags, "DPCONNECTION_DIRECTPLAY,");
272 if (dwFlags & DPCONNECTION_DIRECTPLAYLOBBY)
273 strcat(flags, "DPCONNECTION_DIRECTPLAYLOBBY,");
274 }
275
276 /* EnumPlayers,
277 EnumGroups */
278
279 if (flagType & FLAGS_DPENUMPLAYERS)
280 {
281 if (dwFlags == DPENUMPLAYERS_ALL)
282 strcat(flags, "DPENUMPLAYERS_ALL,");
283 if (dwFlags & DPENUMPLAYERS_LOCAL)
284 strcat(flags, "DPENUMPLAYERS_LOCAL,");
285 if (dwFlags & DPENUMPLAYERS_REMOTE)
286 strcat(flags, "DPENUMPLAYERS_REMOTE,");
287 if (dwFlags & DPENUMPLAYERS_GROUP)
288 strcat(flags, "DPENUMPLAYERS_GROUP,");
289 if (dwFlags & DPENUMPLAYERS_SESSION)
290 strcat(flags, "DPENUMPLAYERS_SESSION,");
291 if (dwFlags & DPENUMPLAYERS_SERVERPLAYER)
292 strcat(flags, "DPENUMPLAYERS_SERVERPLAYER,");
293 if (dwFlags & DPENUMPLAYERS_SPECTATOR)
294 strcat(flags, "DPENUMPLAYERS_SPECTATOR,");
295 if (dwFlags & DPENUMPLAYERS_OWNER)
296 strcat(flags, "DPENUMPLAYERS_OWNER,");
297 }
298 if (flagType & FLAGS_DPENUMGROUPS)
299 {
300 if (dwFlags == DPENUMGROUPS_ALL)
301 strcat(flags, "DPENUMGROUPS_ALL,");
302 if (dwFlags & DPENUMPLAYERS_LOCAL)
303 strcat(flags, "DPENUMGROUPS_LOCAL,");
304 if (dwFlags & DPENUMPLAYERS_REMOTE)
305 strcat(flags, "DPENUMGROUPS_REMOTE,");
306 if (dwFlags & DPENUMPLAYERS_GROUP)
307 strcat(flags, "DPENUMGROUPS_GROUP,");
308 if (dwFlags & DPENUMPLAYERS_SESSION)
309 strcat(flags, "DPENUMGROUPS_SESSION,");
310 if (dwFlags & DPENUMGROUPS_SHORTCUT)
311 strcat(flags, "DPENUMGROUPS_SHORTCUT,");
312 if (dwFlags & DPENUMGROUPS_STAGINGAREA)
313 strcat(flags, "DPENUMGROUPS_STAGINGAREA,");
314 if (dwFlags & DPENUMGROUPS_HIDDEN)
315 strcat(flags, "DPENUMGROUPS_HIDDEN,");
316 }
317
318 /* CreatePlayer */
319
320 if (flagType & FLAGS_DPPLAYER)
321 {
322 if (dwFlags & DPPLAYER_SERVERPLAYER)
323 strcat(flags, "DPPLAYER_SERVERPLAYER,");
324 if (dwFlags & DPPLAYER_SPECTATOR)
325 strcat(flags, "DPPLAYER_SPECTATOR,");
326 if (dwFlags & DPPLAYER_LOCAL)
327 strcat(flags, "DPPLAYER_LOCAL,");
328 if (dwFlags & DPPLAYER_OWNER)
329 strcat(flags, "DPPLAYER_OWNER,");
330 }
331
332 /* CreateGroup */
333
334 if (flagType & FLAGS_DPGROUP)
335 {
336 if (dwFlags & DPGROUP_STAGINGAREA)
337 strcat(flags, "DPGROUP_STAGINGAREA,");
338 if (dwFlags & DPGROUP_LOCAL)
339 strcat(flags, "DPGROUP_LOCAL,");
340 if (dwFlags & DPGROUP_HIDDEN)
341 strcat(flags, "DPGROUP_HIDDEN,");
342 }
343
344 /* EnumSessions */
345
346 if (flagType & FLAGS_DPENUMSESSIONS)
347 {
348 if (dwFlags & DPENUMSESSIONS_AVAILABLE)
349 strcat(flags, "DPENUMSESSIONS_AVAILABLE,");
350 if (dwFlags & DPENUMSESSIONS_ALL)
351 strcat(flags, "DPENUMSESSIONS_ALL,");
352 if (dwFlags & DPENUMSESSIONS_ASYNC)
353 strcat(flags, "DPENUMSESSIONS_ASYNC,");
354 if (dwFlags & DPENUMSESSIONS_STOPASYNC)
355 strcat(flags, "DPENUMSESSIONS_STOPASYNC,");
356 if (dwFlags & DPENUMSESSIONS_PASSWORDREQUIRED)
357 strcat(flags, "DPENUMSESSIONS_PASSWORDREQUIRED,");
358 if (dwFlags & DPENUMSESSIONS_RETURNSTATUS)
359 strcat(flags, "DPENUMSESSIONS_RETURNSTATUS,");
360 }
361
362 /* GetCaps,
363 GetPlayerCaps */
364
365 if (flagType & FLAGS_DPGETCAPS)
366 {
367 if (dwFlags & DPGETCAPS_GUARANTEED)
368 strcat(flags, "DPGETCAPS_GUARANTEED,");
369 }
370
371 /* GetGroupData,
372 GetPlayerData */
373
374 if (flagType & FLAGS_DPGET)
375 {
376 if (dwFlags == DPGET_REMOTE)
377 strcat(flags, "DPGET_REMOTE,");
378 if (dwFlags & DPGET_LOCAL)
379 strcat(flags, "DPGET_LOCAL,");
380 }
381
382 /* Receive */
383
384 if (flagType & FLAGS_DPRECEIVE)
385 {
386 if (dwFlags & DPRECEIVE_ALL)
387 strcat(flags, "DPRECEIVE_ALL,");
388 if (dwFlags & DPRECEIVE_TOPLAYER)
389 strcat(flags, "DPRECEIVE_TOPLAYER,");
390 if (dwFlags & DPRECEIVE_FROMPLAYER)
391 strcat(flags, "DPRECEIVE_FROMPLAYER,");
392 if (dwFlags & DPRECEIVE_PEEK)
393 strcat(flags, "DPRECEIVE_PEEK,");
394 }
395
396 /* Send */
397
398 if (flagType & FLAGS_DPSEND)
399 {
400 /*if (dwFlags == DPSEND_NONGUARANTEED)
401 strcat(flags, "DPSEND_NONGUARANTEED,");*/
402 if (dwFlags == DPSEND_MAX_PRIORITY) /* = DPSEND_MAX_PRI */
403 {
404 strcat(flags, "DPSEND_MAX_PRIORITY,");
405 }
406 else
407 {
408 if (dwFlags & DPSEND_GUARANTEED)
409 strcat(flags, "DPSEND_GUARANTEED,");
410 if (dwFlags & DPSEND_HIGHPRIORITY)
411 strcat(flags, "DPSEND_HIGHPRIORITY,");
412 if (dwFlags & DPSEND_OPENSTREAM)
413 strcat(flags, "DPSEND_OPENSTREAM,");
414 if (dwFlags & DPSEND_CLOSESTREAM)
415 strcat(flags, "DPSEND_CLOSESTREAM,");
416 if (dwFlags & DPSEND_SIGNED)
417 strcat(flags, "DPSEND_SIGNED,");
418 if (dwFlags & DPSEND_ENCRYPTED)
419 strcat(flags, "DPSEND_ENCRYPTED,");
420 if (dwFlags & DPSEND_LOBBYSYSTEMMESSAGE)
421 strcat(flags, "DPSEND_LOBBYSYSTEMMESSAGE,");
422 if (dwFlags & DPSEND_ASYNC)
423 strcat(flags, "DPSEND_ASYNC,");
424 if (dwFlags & DPSEND_NOSENDCOMPLETEMSG)
425 strcat(flags, "DPSEND_NOSENDCOMPLETEMSG,");
426 }
427 }
428
429 /* SetGroupData,
430 SetGroupName,
431 SetPlayerData,
432 SetPlayerName,
433 SetSessionDesc */
434
435 if (flagType & FLAGS_DPSET)
436 {
437 if (dwFlags == DPSET_REMOTE)
438 strcat(flags, "DPSET_REMOTE,");
439 if (dwFlags & DPSET_LOCAL)
440 strcat(flags, "DPSET_LOCAL,");
441 if (dwFlags & DPSET_GUARANTEED)
442 strcat(flags, "DPSET_GUARANTEED,");
443 }
444
445 /* GetMessageQueue */
446
447 if (flagType & FLAGS_DPMESSAGEQUEUE)
448 {
449 if (dwFlags & DPMESSAGEQUEUE_SEND)
450 strcat(flags, "DPMESSAGEQUEUE_SEND,");
451 if (dwFlags & DPMESSAGEQUEUE_RECEIVE)
452 strcat(flags, "DPMESSAGEQUEUE_RECEIVE,");
453 }
454
455 /* Connect */
456
457 if (flagType & FLAGS_DPCONNECT)
458 {
459 if (dwFlags & DPCONNECT_RETURNSTATUS)
460 strcat(flags, "DPCONNECT_RETURNSTATUS,");
461 }
462
463 /* Open */
464
465 if (flagType & FLAGS_DPOPEN)
466 {
467 if (dwFlags & DPOPEN_JOIN)
468 strcat(flags, "DPOPEN_JOIN,");
469 if (dwFlags & DPOPEN_CREATE)
470 strcat(flags, "DPOPEN_CREATE,");
471 if (dwFlags & DPOPEN_RETURNSTATUS)
472 strcat(flags, "DPOPEN_RETURNSTATUS,");
473 }
474
475 /* DPSESSIONDESC2 */
476
477 if (flagType & FLAGS_DPSESSION)
478 {
479 if (dwFlags & DPSESSION_NEWPLAYERSDISABLED)
480 strcat(flags, "DPSESSION_NEWPLAYERSDISABLED,");
481 if (dwFlags & DPSESSION_MIGRATEHOST)
482 strcat(flags, "DPSESSION_MIGRATEHOST,");
483 if (dwFlags & DPSESSION_NOMESSAGEID)
484 strcat(flags, "DPSESSION_NOMESSAGEID,");
485 if (dwFlags & DPSESSION_JOINDISABLED)
486 strcat(flags, "DPSESSION_JOINDISABLED,");
487 if (dwFlags & DPSESSION_KEEPALIVE)
488 strcat(flags, "DPSESSION_KEEPALIVE,");
489 if (dwFlags & DPSESSION_NODATAMESSAGES)
490 strcat(flags, "DPSESSION_NODATAMESSAGES,");
491 if (dwFlags & DPSESSION_SECURESERVER)
492 strcat(flags, "DPSESSION_SECURESERVER,");
493 if (dwFlags & DPSESSION_PRIVATE)
494 strcat(flags, "DPSESSION_PRIVATE,");
495 if (dwFlags & DPSESSION_PASSWORDREQUIRED)
496 strcat(flags, "DPSESSION_PASSWORDREQUIRED,");
497 if (dwFlags & DPSESSION_MULTICASTSERVER)
498 strcat(flags, "DPSESSION_MULTICASTSERVER,");
499 if (dwFlags & DPSESSION_CLIENTSERVER)
500 strcat(flags, "DPSESSION_CLIENTSERVER,");
501
502 if (dwFlags & DPSESSION_DIRECTPLAYPROTOCOL)
503 strcat(flags, "DPSESSION_DIRECTPLAYPROTOCOL,");
504 if (dwFlags & DPSESSION_NOPRESERVEORDER)
505 strcat(flags, "DPSESSION_NOPRESERVEORDER,");
506 if (dwFlags & DPSESSION_OPTIMIZELATENCY)
507 strcat(flags, "DPSESSION_OPTIMIZELATENCY,");
508
509 }
510
511 /* DPLCONNECTION */
512
513 if (flagType & FLAGS_DPLCONNECTION)
514 {
515 if (dwFlags & DPLCONNECTION_CREATESESSION)
516 strcat(flags, "DPLCONNECTION_CREATESESSION,");
517 if (dwFlags & DPLCONNECTION_JOINSESSION)
518 strcat(flags, "DPLCONNECTION_JOINSESSION,");
519 }
520
521 /* EnumSessionsCallback2 */
522
523 if (flagType & FLAGS_DPESC)
524 {
525 if (dwFlags & DPESC_TIMEDOUT)
526 strcat(flags, "DPESC_TIMEDOUT,");
527 }
528
529 /* GetCaps,
530 GetPlayerCaps */
531
532 if (flagType & FLAGS_DPCAPS)
533 {
534 if (dwFlags & DPCAPS_ISHOST)
535 strcat(flags, "DPCAPS_ISHOST,");
536 if (dwFlags & DPCAPS_GROUPOPTIMIZED)
537 strcat(flags, "DPCAPS_GROUPOPTIMIZED,");
538 if (dwFlags & DPCAPS_KEEPALIVEOPTIMIZED)
539 strcat(flags, "DPCAPS_KEEPALIVEOPTIMIZED,");
540 if (dwFlags & DPCAPS_GUARANTEEDOPTIMIZED)
541 strcat(flags, "DPCAPS_GUARANTEEDOPTIMIZED,");
542 if (dwFlags & DPCAPS_GUARANTEEDSUPPORTED)
543 strcat(flags, "DPCAPS_GUARANTEEDSUPPORTED,");
544 if (dwFlags & DPCAPS_SIGNINGSUPPORTED)
545 strcat(flags, "DPCAPS_SIGNINGSUPPORTED,");
546 if (dwFlags & DPCAPS_ENCRYPTIONSUPPORTED)
547 strcat(flags, "DPCAPS_ENCRYPTIONSUPPORTED,");
548 if (dwFlags & DPCAPS_ASYNCCANCELSUPPORTED)
549 strcat(flags, "DPCAPS_ASYNCCANCELSUPPORTED,");
550 if (dwFlags & DPCAPS_ASYNCCANCELALLSUPPORTED)
551 strcat(flags, "DPCAPS_ASYNCCANCELALLSUPPORTED,");
552 if (dwFlags & DPCAPS_SENDTIMEOUTSUPPORTED)
553 strcat(flags, "DPCAPS_SENDTIMEOUTSUPPORTED,");
554 if (dwFlags & DPCAPS_SENDPRIORITYSUPPORTED)
555 strcat(flags, "DPCAPS_SENDPRIORITYSUPPORTED,");
556 if (dwFlags & DPCAPS_ASYNCSUPPORTED)
557 strcat(flags, "DPCAPS_ASYNCSUPPORTED,");
558
559 if (dwFlags & DPPLAYERCAPS_LOCAL)
560 strcat(flags, "DPPLAYERCAPS_LOCAL,");
561 }
562
563 if ((strlen(flags) == 0) && (dwFlags != 0))
564 strcpy(flags, "UNKNOWN");
565 else
566 flags[strlen(flags)-1] = '\0';
567
568 return flags;
569 }
570
571 static char dpid2char(DPID* dpid, DWORD dpidSize, DPID idPlayer)
572 {
573 UINT i;
574 if ( idPlayer == DPID_SYSMSG )
575 return 'S';
576 for (i=0; i<dpidSize; i++)
577 {
578 if ( idPlayer == dpid[i] )
579 return (char)(i+48);
580 }
581 return '?';
582 }
583
584 static void check_messages( LPDIRECTPLAY4 pDP,
585 DPID *dpid,
586 DWORD dpidSize,
587 lpCallbackData callbackData )
588 {
589 /* Retrieves all messages from the queue of pDP, performing tests
590 * to check if we are receiving what we expect.
591 *
592 * Information about the messages is stores in callbackData:
593 *
594 * callbackData->dwCounter1: Number of messages received.
595 * callbackData->szTrace1: Traces for sender and receiver.
596 * We store the position a dpid holds in the dpid array.
597 * Example:
598 *
599 * trace string: "01,02,03,14"
600 * expanded: [ '01', '02', '03', '14' ]
601 * \ \ \ \
602 * \ \ \ ) message 3: from 1 to 4
603 * \ \ ) message 2: from 0 to 3
604 * \ ) message 1: from 0 to 2
605 * ) message 0: from 0 to 1
606 *
607 * In general terms:
608 * sender of message i = character in place 3*i of the array
609 * receiver of message i = character in place 3*i+1 of the array
610 *
611 * A sender value of 'S' means DPID_SYSMSG, this is, a system message.
612 *
613 * callbackData->szTrace2: Traces for message sizes.
614 */
615
616 DPID idFrom, idTo;
617 UINT i;
618 DWORD dwDataSize = 1024;
619 LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
620 HRESULT hr;
621 char temp[5];
622
623 callbackData->szTrace2[0] = '\0';
624
625 i = 0;
626 while ( DP_OK == (hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
627 lpData, &dwDataSize )) )
628 {
629
630 callbackData->szTrace1[ 3*i ] = dpid2char( dpid, dpidSize, idFrom );
631 callbackData->szTrace1[ 3*i+1 ] = dpid2char( dpid, dpidSize, idTo );
632 callbackData->szTrace1[ 3*i+2 ] = ',';
633
634 sprintf( temp, "%d,", dwDataSize );
635 strcat( callbackData->szTrace2, temp );
636
637 dwDataSize = 1024;
638 ++i;
639 }
640
641 checkHR( DPERR_NOMESSAGES, hr );
642
643 callbackData->szTrace1[ 3*i ] = '\0';
644 callbackData->dwCounter1 = i;
645
646
647 HeapFree( GetProcessHeap(), 0, lpData );
648 }
649
650 static void init_TCPIP_provider( LPDIRECTPLAY4 pDP,
651 LPCSTR strIPAddressString,
652 WORD port )
653 {
654
655 DPCOMPOUNDADDRESSELEMENT addressElements[3];
656 LPVOID pAddress = NULL;
657 DWORD dwAddressSize = 0;
658 LPDIRECTPLAYLOBBY3 pDPL;
659 HRESULT hr;
660
661 CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
662 &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
663
664 /* Service provider */
665 addressElements[0].guidDataType = DPAID_ServiceProvider;
666 addressElements[0].dwDataSize = sizeof(GUID);
667 addressElements[0].lpData = (LPVOID) &DPSPGUID_TCPIP;
668
669 /* IP address string */
670 addressElements[1].guidDataType = DPAID_INet;
671 addressElements[1].dwDataSize = lstrlen(strIPAddressString) + 1;
672 addressElements[1].lpData = (LPVOID) strIPAddressString;
673
674 /* Optional Port number */
675 if( port > 0 )
676 {
677 addressElements[2].guidDataType = DPAID_INetPort;
678 addressElements[2].dwDataSize = sizeof(WORD);
679 addressElements[2].lpData = &port;
680 }
681
682
683 hr = IDirectPlayLobby_CreateCompoundAddress( pDPL, addressElements, 2,
684 NULL, &dwAddressSize );
685 checkHR( DPERR_BUFFERTOOSMALL, hr );
686
687 if( hr == DPERR_BUFFERTOOSMALL )
688 {
689 pAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressSize );
690 hr = IDirectPlayLobby_CreateCompoundAddress( pDPL, addressElements, 2,
691 pAddress, &dwAddressSize );
692 checkHR( DP_OK, hr );
693 }
694
695 hr = IDirectPlayX_InitializeConnection( pDP, pAddress, 0 );
696 todo_wine checkHR( DP_OK, hr );
697
698 HeapFree( GetProcessHeap(), 0, pAddress );
699
700 }
701
702 static BOOL CALLBACK EnumSessions_cb_join( LPCDPSESSIONDESC2 lpThisSD,
703 LPDWORD lpdwTimeOut,
704 DWORD dwFlags,
705 LPVOID lpContext )
706 {
707 LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
708 DPSESSIONDESC2 dpsd;
709 HRESULT hr;
710
711 if (dwFlags & DPESC_TIMEDOUT)
712 {
713 return FALSE;
714 }
715
716 ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
717 dpsd.dwSize = sizeof(DPSESSIONDESC2);
718 dpsd.guidApplication = appGuid;
719 dpsd.guidInstance = lpThisSD->guidInstance;
720
721 hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
722 checkHR( DP_OK, hr );
723
724 return TRUE;
725 }
726
727
728 /* DirectPlayCreate */
729
730 static void test_DirectPlayCreate(void)
731 {
732
733 LPDIRECTPLAY pDP;
734 HRESULT hr;
735
736 /* TODO: Check how it behaves with pUnk!=NULL */
737
738 /* pDP==NULL */
739 hr = DirectPlayCreate( NULL, NULL, NULL );
740 checkHR( DPERR_INVALIDPARAMS, hr );
741 hr = DirectPlayCreate( (LPGUID) &GUID_NULL, NULL, NULL );
742 checkHR( DPERR_INVALIDPARAMS, hr );
743 hr = DirectPlayCreate( (LPGUID) &DPSPGUID_TCPIP, NULL, NULL );
744 checkHR( DPERR_INVALIDPARAMS, hr );
745
746 /* pUnk==NULL, pDP!=NULL */
747 hr = DirectPlayCreate( NULL, &pDP, NULL );
748 checkHR( DPERR_INVALIDPARAMS, hr );
749 hr = DirectPlayCreate( (LPGUID) &GUID_NULL, &pDP, NULL );
750 checkHR( DP_OK, hr );
751 if ( hr == DP_OK )
752 IDirectPlayX_Release( pDP );
753 hr = DirectPlayCreate( (LPGUID) &DPSPGUID_TCPIP, &pDP, NULL );
754 todo_wine checkHR( DP_OK, hr );
755 if ( hr == DP_OK )
756 IDirectPlayX_Release( pDP );
757
758 }
759
760 /* EnumConnections */
761
762 static BOOL CALLBACK EnumAddress_cb2( REFGUID guidDataType,
763 DWORD dwDataSize,
764 LPCVOID lpData,
765 LPVOID lpContext )
766 {
767 lpCallbackData callbackData = (lpCallbackData) lpContext;
768
769 static REFGUID types[] = { &DPAID_TotalSize,
770 &DPAID_ServiceProvider,
771 &GUID_NULL };
772 static DWORD sizes[] = { 4, 16, 0 };
773 static REFGUID sps[] = { &DPSPGUID_SERIAL, &DPSPGUID_MODEM,
774 &DPSPGUID_IPX, &DPSPGUID_TCPIP };
775
776
777 checkGuid( types[ callbackData->dwCounter2 ], guidDataType );
778 check( sizes[ callbackData->dwCounter2 ], dwDataSize );
779
780 if ( IsEqualGUID( types[0], guidDataType ) )
781 {
782 todo_wine check( 80, *((LPDWORD) lpData) );
783 }
784 else if ( IsEqualGUID( types[1], guidDataType ) )
785 {
786 todo_wine checkGuid( sps[ callbackData->dwCounter1 ], (LPGUID) lpData );
787 }
788
789 callbackData->dwCounter2++;
790
791 return TRUE;
792 }
793
794 static BOOL CALLBACK EnumConnections_cb( LPCGUID lpguidSP,
795 LPVOID lpConnection,
796 DWORD dwConnectionSize,
797 LPCDPNAME lpName,
798 DWORD dwFlags,
799 LPVOID lpContext )
800 {
801
802 lpCallbackData callbackData = (lpCallbackData) lpContext;
803 LPDIRECTPLAYLOBBY pDPL;
804
805
806 if (!callbackData->dwFlags)
807 {
808 callbackData->dwFlags = DPCONNECTION_DIRECTPLAY;
809 }
810
811 checkFlags( callbackData->dwFlags, dwFlags, FLAGS_DPCONNECTION );
812
813 /* Get info from lpConnection */
814 CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
815 &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
816
817 callbackData->dwCounter2 = 0;
818 IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb2,
819 (LPCVOID) lpConnection,
820 dwConnectionSize,
821 (LPVOID) callbackData );
822 todo_wine check( 3, callbackData->dwCounter2 );
823
824 callbackData->dwCounter1++;
825
826 return TRUE;
827 }
828
829 static void test_EnumConnections(void)
830 {