dplayx/tests: Fix compilation on systems that don't support nameless unions.
[wine] / dlls / dplayx / tests / dplayx.c
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 ], 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, lpConnection,
819                                   dwConnectionSize, callbackData );
820     todo_wine check( 3, callbackData->dwCounter2 );
821
822     callbackData->dwCounter1++;
823
824     return TRUE;
825 }
826
827 static void test_EnumConnections(void)
828 {
829
830     LPDIRECTPLAY4 pDP;
831     CallbackData callbackData;
832     HRESULT hr;
833
834
835     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
836                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
837
838
839     callbackData.dwCounter1 = 0;
840     callbackData.dwFlags = 0;
841     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
842                                        &callbackData, callbackData.dwFlags );
843     checkHR( DP_OK, hr );
844     check( 4, callbackData.dwCounter1 );
845
846     callbackData.dwCounter1 = 0;
847     callbackData.dwFlags = 0;
848     hr = IDirectPlayX_EnumConnections( pDP, NULL, EnumConnections_cb,
849                                        &callbackData, callbackData.dwFlags );
850     checkHR( DP_OK, hr );
851     check( 4, callbackData.dwCounter1 );
852
853     callbackData.dwCounter1 = 0;
854     callbackData.dwFlags = 0;
855     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, NULL,
856                                        &callbackData, callbackData.dwFlags );
857     checkHR( DPERR_INVALIDPARAMS, hr );
858     check( 0, callbackData.dwCounter1 );
859
860
861     /* Flag tests */
862     callbackData.dwCounter1 = 0;
863     callbackData.dwFlags = DPCONNECTION_DIRECTPLAY;
864     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
865                                        &callbackData, callbackData.dwFlags );
866     checkHR( DP_OK, hr );
867     check( 4, callbackData.dwCounter1 );
868
869     callbackData.dwCounter1 = 0;
870     callbackData.dwFlags = DPCONNECTION_DIRECTPLAYLOBBY;
871     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
872                                        &callbackData, callbackData.dwFlags );
873     checkHR( DP_OK, hr );
874     check( 0, callbackData.dwCounter1 );
875
876     callbackData.dwCounter1 = 0;
877     callbackData.dwFlags = ( DPCONNECTION_DIRECTPLAY |
878                              DPCONNECTION_DIRECTPLAYLOBBY );
879     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
880                                        &callbackData, callbackData.dwFlags );
881     checkHR( DP_OK, hr );
882     check( 4, callbackData.dwCounter1 );
883
884     callbackData.dwCounter1 = 0;
885     callbackData.dwFlags = ~( DPCONNECTION_DIRECTPLAY |
886                               DPCONNECTION_DIRECTPLAYLOBBY );
887     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
888                                        &callbackData, callbackData.dwFlags );
889     checkHR( DPERR_INVALIDFLAGS, hr );
890     check( 0, callbackData.dwCounter1 );
891
892
893     IDirectPlayX_Release( pDP );
894 }
895
896 /* InitializeConnection */
897
898 static BOOL CALLBACK EnumConnections_cb2( LPCGUID lpguidSP,
899                                           LPVOID lpConnection,
900                                           DWORD dwConnectionSize,
901                                           LPCDPNAME lpName,
902                                           DWORD dwFlags,
903                                           LPVOID lpContext )
904 {
905     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
906     HRESULT hr;
907
908     /* Incorrect parameters */
909     hr = IDirectPlayX_InitializeConnection( pDP, NULL, 1 );
910     checkHR( DPERR_INVALIDPARAMS, hr );
911     hr = IDirectPlayX_InitializeConnection( pDP, lpConnection, 1 );
912     checkHR( DPERR_INVALIDFLAGS, hr );
913
914     /* Normal operation.
915        We're only interested in ensuring that the TCP/IP provider works */
916
917     if( IsEqualGUID(lpguidSP, &DPSPGUID_TCPIP) )
918     {
919         hr = IDirectPlayX_InitializeConnection( pDP, lpConnection, 0 );
920         todo_wine checkHR( DP_OK, hr );
921         hr = IDirectPlayX_InitializeConnection( pDP, lpConnection, 0 );
922         todo_wine checkHR( DPERR_ALREADYINITIALIZED, hr );
923     }
924
925     return TRUE;
926 }
927
928 static void test_InitializeConnection(void)
929 {
930
931     LPDIRECTPLAY4 pDP;
932
933     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
934                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
935
936     IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb2, pDP, 0 );
937
938     IDirectPlayX_Release( pDP );
939 }
940
941 /* GetCaps */
942
943 static void test_GetCaps(void)
944 {
945
946     LPDIRECTPLAY4 pDP;
947     DPCAPS dpcaps;
948     DWORD dwFlags;
949     HRESULT hr;
950
951
952     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
953                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
954     ZeroMemory( &dpcaps, sizeof(DPCAPS) );
955
956     /* Service provider not ininitialized */
957     hr = IDirectPlayX_GetCaps( pDP, &dpcaps, 0 );
958     checkHR( DPERR_UNINITIALIZED, hr );
959
960     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
961
962     /* dpcaps not ininitialized */
963     hr = IDirectPlayX_GetCaps( pDP, &dpcaps, 0 );
964     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
965
966     dpcaps.dwSize = sizeof(DPCAPS);
967
968     for (dwFlags=0;
969          dwFlags<=DPGETCAPS_GUARANTEED;
970          dwFlags+=DPGETCAPS_GUARANTEED)
971     {
972
973         hr = IDirectPlayX_GetCaps( pDP, &dpcaps, dwFlags );
974         todo_wine checkHR( DP_OK, hr );
975
976
977         if ( hr == DP_OK )
978         {
979             check( sizeof(DPCAPS), dpcaps.dwSize );
980             check( DPCAPS_ASYNCSUPPORTED |
981                    DPCAPS_GUARANTEEDOPTIMIZED |
982                    DPCAPS_GUARANTEEDSUPPORTED,
983                    dpcaps.dwFlags );
984             check( 0,     dpcaps.dwMaxQueueSize );
985             check( 0,     dpcaps.dwHundredBaud );
986             check( 500,   dpcaps.dwLatency );
987             check( 65536, dpcaps.dwMaxLocalPlayers );
988             check( 20,    dpcaps.dwHeaderLength );
989             check( 5000,  dpcaps.dwTimeout );
990
991             switch (dwFlags)
992             {
993             case 0:
994                 check( 65479,   dpcaps.dwMaxBufferSize );
995                 check( 65536,   dpcaps.dwMaxPlayers );
996                 break;
997             case DPGETCAPS_GUARANTEED:
998                 check( 1048547, dpcaps.dwMaxBufferSize );
999                 check( 64,      dpcaps.dwMaxPlayers );
1000                 break;
1001             default: break;
1002             }
1003         }
1004     }
1005
1006     IDirectPlayX_Release( pDP );
1007 }
1008
1009 /* Open */
1010
1011 static BOOL CALLBACK EnumSessions_cb2( LPCDPSESSIONDESC2 lpThisSD,
1012                                        LPDWORD lpdwTimeOut,
1013                                        DWORD dwFlags,
1014                                        LPVOID lpContext )
1015 {
1016     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
1017     DPSESSIONDESC2 dpsd;
1018     HRESULT hr;
1019
1020     if (dwFlags & DPESC_TIMEDOUT)
1021         return FALSE;
1022
1023
1024     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1025     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1026     dpsd.guidApplication = appGuid;
1027     dpsd.guidInstance = lpThisSD->guidInstance;
1028
1029     if ( lpThisSD->dwFlags & DPSESSION_PASSWORDREQUIRED )
1030     {
1031         /* Incorrect password */
1032         U2(dpsd).lpszPasswordA = (LPSTR) "sonic boom";
1033         hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1034         checkHR( DPERR_INVALIDPASSWORD, hr );
1035
1036         /* Correct password */
1037         U2(dpsd).lpszPasswordA = (LPSTR) "hadouken";
1038         hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1039         checkHR( DP_OK, hr );
1040     }
1041     else
1042     {
1043         hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1044         checkHR( DP_OK, hr );
1045     }
1046
1047     hr = IDirectPlayX_Close( pDP );
1048     checkHR( DP_OK, hr );
1049
1050     return TRUE;
1051 }
1052
1053 static void test_Open(void)
1054 {
1055
1056     LPDIRECTPLAY4 pDP, pDP_server;
1057     DPSESSIONDESC2 dpsd, dpsd_server;
1058     HRESULT hr;
1059
1060
1061     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1062                       &IID_IDirectPlay4A, (LPVOID*) &pDP_server );
1063     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1064                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
1065     ZeroMemory( &dpsd_server, sizeof(DPSESSIONDESC2) );
1066     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1067
1068     /* Service provider not initialized */
1069     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1070     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1071
1072     init_TCPIP_provider( pDP_server, "127.0.0.1", 0 );
1073     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
1074
1075     /* Uninitialized  dpsd */
1076     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1077     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1078
1079
1080     dpsd_server.dwSize = sizeof(DPSESSIONDESC2);
1081     dpsd_server.guidApplication = appGuid;
1082     dpsd_server.dwMaxPlayers = 10;
1083
1084
1085     /* Regular operation */
1086     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1087     todo_wine checkHR( DP_OK, hr );
1088
1089     /* Opening twice */
1090     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1091     todo_wine checkHR( DPERR_ALREADYINITIALIZED, hr );
1092
1093     /* Session flags */
1094     IDirectPlayX_Close( pDP_server );
1095
1096     dpsd_server.dwFlags = DPSESSION_CLIENTSERVER | DPSESSION_MIGRATEHOST;
1097     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1098     todo_wine checkHR( DPERR_INVALIDFLAGS, hr );
1099
1100     dpsd_server.dwFlags = DPSESSION_MULTICASTSERVER | DPSESSION_MIGRATEHOST;
1101     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1102     todo_wine checkHR( DPERR_INVALIDFLAGS, hr );
1103
1104     dpsd_server.dwFlags = DPSESSION_SECURESERVER | DPSESSION_MIGRATEHOST;
1105     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1106     todo_wine checkHR( DPERR_INVALIDFLAGS, hr );
1107
1108
1109     /* Joining sessions */
1110     /* - Checking how strict dplay is with sizes */
1111     dpsd.dwSize = 0;
1112     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1113     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1114
1115     dpsd.dwSize = sizeof(DPSESSIONDESC2)-1;
1116     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1117     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1118
1119     dpsd.dwSize = sizeof(DPSESSIONDESC2)+1;
1120     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1121     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1122
1123     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1124     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1125     todo_wine checkHR( DPERR_NOSESSIONS, hr ); /* Only checks for size, not guids */
1126
1127
1128     dpsd.guidApplication = appGuid;
1129     dpsd.guidInstance = appGuid;
1130
1131
1132     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1133     todo_wine checkHR( DPERR_NOSESSIONS, hr );
1134     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN | DPOPEN_CREATE );
1135     todo_wine checkHR( DPERR_NOSESSIONS, hr ); /* Second flag is ignored */
1136
1137     dpsd_server.dwFlags = 0;
1138
1139
1140     /* Join to normal session */
1141     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1142     todo_wine checkHR( DP_OK, hr );
1143
1144     IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb2, pDP, 0 );
1145
1146
1147     /* Already initialized session */
1148     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1149     todo_wine checkHR( DPERR_ALREADYINITIALIZED, hr );
1150
1151
1152     /* Checking which is the error checking order */
1153     dpsd_server.dwSize = 0;
1154
1155     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1156     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1157
1158     dpsd_server.dwSize = sizeof(DPSESSIONDESC2);
1159
1160
1161     /* Join to protected session */
1162     IDirectPlayX_Close( pDP_server );
1163     U2(dpsd_server).lpszPasswordA = (LPSTR) "hadouken";
1164     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1165     todo_wine checkHR( DP_OK, hr );
1166
1167     IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb2,
1168                                pDP, DPENUMSESSIONS_PASSWORDREQUIRED );
1169
1170
1171     IDirectPlayX_Release( pDP );
1172     IDirectPlayX_Release( pDP_server );
1173
1174 }
1175
1176 /* EnumSessions */
1177
1178 static BOOL CALLBACK EnumSessions_cb( LPCDPSESSIONDESC2 lpThisSD,
1179                                       LPDWORD lpdwTimeOut,
1180                                       DWORD dwFlags,
1181                                       LPVOID lpContext )
1182 {
1183     lpCallbackData callbackData = (lpCallbackData) lpContext;
1184     callbackData->dwCounter1++;
1185
1186     if ( dwFlags & DPESC_TIMEDOUT )
1187     {
1188         check( TRUE, lpThisSD == NULL );
1189         return FALSE;
1190     }
1191     check( FALSE, lpThisSD == NULL );
1192
1193
1194     if ( U2(*lpThisSD).lpszPasswordA != NULL )
1195     {
1196         check( TRUE, (lpThisSD->dwFlags & DPSESSION_PASSWORDREQUIRED) != 0 );
1197     }
1198
1199     if ( lpThisSD->dwFlags & DPSESSION_NEWPLAYERSDISABLED )
1200     {
1201         check( 0, lpThisSD->dwCurrentPlayers );
1202     }
1203
1204     check( sizeof(*lpThisSD), lpThisSD->dwSize );
1205     checkLP( NULL, U2(*lpThisSD).lpszPasswordA );
1206
1207     return TRUE;
1208 }
1209
1210 static LPDIRECTPLAY4 create_session(DPSESSIONDESC2 *lpdpsd)
1211 {
1212
1213     LPDIRECTPLAY4 pDP;
1214     DPNAME name;
1215     DPID dpid;
1216     HRESULT hr;
1217
1218     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1219                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
1220
1221     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
1222
1223     hr = IDirectPlayX_Open( pDP, lpdpsd, DPOPEN_CREATE );
1224     todo_wine checkHR( DP_OK, hr );
1225
1226     if ( ! (lpdpsd->dwFlags & DPSESSION_NEWPLAYERSDISABLED) )
1227     {
1228         ZeroMemory( &name, sizeof(DPNAME) );
1229         name.dwSize = sizeof(DPNAME);
1230         U1(name).lpszShortNameA = (LPSTR) "bofh";
1231
1232         hr = IDirectPlayX_CreatePlayer( pDP, &dpid, &name, NULL, NULL,
1233                                         0, DPPLAYER_SERVERPLAYER );
1234         todo_wine checkHR( DP_OK, hr );
1235     }
1236
1237     return pDP;
1238
1239 }
1240
1241 static void test_EnumSessions(void)
1242 {
1243
1244 #define N_SESSIONS 6
1245
1246     LPDIRECTPLAY4 pDP, pDPserver[N_SESSIONS];
1247     DPSESSIONDESC2 dpsd, dpsd_server[N_SESSIONS];
1248     CallbackData callbackData;
1249     HRESULT hr;
1250     UINT i;
1251
1252
1253     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1254                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
1255     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1256     callbackData.dwCounter1 = -1; /* So that after a call to EnumSessions
1257                                      we get the exact number of sessions */
1258     callbackData.dwFlags = 0;
1259
1260
1261     /* Service provider not initialized */
1262     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1263                                     &callbackData, 0 );
1264     checkHR( DPERR_UNINITIALIZED, hr );
1265
1266
1267     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
1268
1269
1270     /* Session with no size */
1271     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1272                                     &callbackData, 0 );
1273     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1274
1275     if ( hr == DPERR_UNINITIALIZED )
1276     {
1277         todo_wine win_skip( "EnumSessions not implemented\n" );
1278         return;
1279     }
1280
1281     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1282
1283
1284     /* No sessions */
1285     callbackData.dwCounter1 = -1;
1286     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1287                                     &callbackData, 0 );
1288     checkHR( DP_OK, hr );
1289     check( 0, callbackData.dwCounter1 );
1290
1291
1292     dpsd.guidApplication = appGuid;
1293
1294     /* Set up sessions */
1295     for (i=0; i<N_SESSIONS; i++)
1296     {
1297         memcpy( &dpsd_server[i], &dpsd, sizeof(DPSESSIONDESC2) );
1298     }
1299
1300     U1(dpsd_server[0]).lpszSessionNameA = (LPSTR) "normal";
1301     dpsd_server[0].dwFlags = ( DPSESSION_CLIENTSERVER |
1302                                DPSESSION_DIRECTPLAYPROTOCOL );
1303     dpsd_server[0].dwMaxPlayers = 10;
1304
1305     U1(dpsd_server[1]).lpszSessionNameA = (LPSTR) "full";
1306     dpsd_server[1].dwFlags = ( DPSESSION_CLIENTSERVER |
1307                                DPSESSION_DIRECTPLAYPROTOCOL );
1308     dpsd_server[1].dwMaxPlayers = 1;
1309
1310     U1(dpsd_server[2]).lpszSessionNameA = (LPSTR) "no new";
1311     dpsd_server[2].dwFlags = ( DPSESSION_CLIENTSERVER |
1312                                DPSESSION_DIRECTPLAYPROTOCOL |
1313                                DPSESSION_NEWPLAYERSDISABLED );
1314     dpsd_server[2].dwMaxPlayers = 10;
1315
1316     U1(dpsd_server[3]).lpszSessionNameA = (LPSTR) "no join";
1317     dpsd_server[3].dwFlags = ( DPSESSION_CLIENTSERVER |
1318                                DPSESSION_DIRECTPLAYPROTOCOL |
1319                                DPSESSION_JOINDISABLED );
1320     dpsd_server[3].dwMaxPlayers = 10;
1321
1322     U1(dpsd_server[4]).lpszSessionNameA = (LPSTR) "private";
1323     dpsd_server[4].dwFlags = ( DPSESSION_CLIENTSERVER |
1324                                DPSESSION_DIRECTPLAYPROTOCOL |
1325                                DPSESSION_PRIVATE );
1326     dpsd_server[4].dwMaxPlayers = 10;
1327     U2(dpsd_server[4]).lpszPasswordA = (LPSTR) "password";
1328
1329     U1(dpsd_server[5]).lpszSessionNameA = (LPSTR) "protected";
1330     dpsd_server[5].dwFlags = ( DPSESSION_CLIENTSERVER |
1331                                DPSESSION_DIRECTPLAYPROTOCOL |
1332                                DPSESSION_PASSWORDREQUIRED );
1333     dpsd_server[5].dwMaxPlayers = 10;
1334     U2(dpsd_server[5]).lpszPasswordA = (LPSTR) "password";
1335
1336
1337     for (i=0; i<N_SESSIONS; i++)
1338     {
1339         pDPserver[i] = create_session( &dpsd_server[i] );
1340     }
1341
1342
1343     /* Invalid params */
1344     callbackData.dwCounter1 = -1;
1345     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1346                                     &callbackData, -1 );
1347     checkHR( DPERR_INVALIDPARAMS, hr );
1348
1349     hr = IDirectPlayX_EnumSessions( pDP, NULL, 0, EnumSessions_cb,
1350                                     &callbackData, 0 );
1351     checkHR( DPERR_INVALIDPARAMS, hr );
1352
1353     check( -1, callbackData.dwCounter1 );
1354
1355
1356     /* Flag tests */
1357     callbackData.dwFlags = DPENUMSESSIONS_ALL; /* Doesn't list private,
1358                                                   protected */
1359     callbackData.dwCounter1 = -1;
1360     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1361                                     &callbackData, callbackData.dwFlags );
1362     check( N_SESSIONS-2, callbackData.dwCounter1 );
1363
1364     /* Doesn't list private */
1365     callbackData.dwFlags = ( DPENUMSESSIONS_ALL |
1366                              DPENUMSESSIONS_PASSWORDREQUIRED );
1367     callbackData.dwCounter1 = -1;
1368     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1369                                     &callbackData, callbackData.dwFlags );
1370     check( N_SESSIONS-1, callbackData.dwCounter1 );
1371
1372     /* Doesn't list full, no new, no join, private, protected */
1373     callbackData.dwFlags = DPENUMSESSIONS_AVAILABLE;
1374     callbackData.dwCounter1 = -1;
1375     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1376                                     &callbackData, callbackData.dwFlags );
1377     check( N_SESSIONS-5, callbackData.dwCounter1 );
1378
1379     /* Like with DPENUMSESSIONS_AVAILABLE */
1380     callbackData.dwFlags = 0;
1381     callbackData.dwCounter1 = -1;
1382     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1383                                     &callbackData, callbackData.dwFlags );
1384     check( N_SESSIONS-5, callbackData.dwCounter1 );
1385
1386     /* Doesn't list full, no new, no join, private */
1387     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1388     callbackData.dwCounter1 = -1;
1389     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1390                                     &callbackData, callbackData.dwFlags );
1391     check( N_SESSIONS-4, callbackData.dwCounter1 );
1392
1393
1394     /* Async enumeration */
1395     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1396     callbackData.dwCounter1 = -1;
1397     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1398                                     &callbackData, callbackData.dwFlags );
1399     check( N_SESSIONS-4, callbackData.dwCounter1 ); /* Read cache of last
1400                                                        sync enumeration */
1401
1402     callbackData.dwFlags = DPENUMSESSIONS_STOPASYNC;
1403     callbackData.dwCounter1 = -1;
1404     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1405                                     &callbackData, callbackData.dwFlags );
1406     check( 0, callbackData.dwCounter1 ); /* Stop enumeration */
1407
1408     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1409     callbackData.dwCounter1 = -1;
1410     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1411                                     &callbackData, callbackData.dwFlags );
1412     check( 0, callbackData.dwCounter1 ); /* Start enumeration */
1413
1414     Sleep(500); /* Give time to fill the cache */
1415
1416     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1417     callbackData.dwCounter1 = -1;
1418     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1419                                     &callbackData, callbackData.dwFlags );
1420     check( N_SESSIONS-5, callbackData.dwCounter1 ); /* Retrieve results */
1421
1422     callbackData.dwFlags = DPENUMSESSIONS_STOPASYNC;
1423     callbackData.dwCounter1 = -1;
1424     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1425                                     &callbackData, callbackData.dwFlags );
1426     check( 0, callbackData.dwCounter1 ); /* Stop enumeration */
1427
1428
1429     /* Specific tests for passworded sessions */
1430
1431     for (i=0; i<N_SESSIONS; i++)
1432     {
1433         IDirectPlayX_Release( pDPserver[i] );
1434     }
1435
1436     /* - Only session password set */
1437     for (i=4;i<=5;i++)
1438     {
1439         U2(dpsd_server[i]).lpszPasswordA = (LPSTR) "password";
1440         dpsd_server[i].dwFlags = 0;
1441         pDPserver[i] = create_session( &dpsd_server[i] );
1442     }
1443
1444     callbackData.dwFlags = 0;
1445     callbackData.dwCounter1 = -1;
1446     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1447                                     &callbackData, callbackData.dwFlags );
1448     check( 0, callbackData.dwCounter1 );
1449
1450     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1451     callbackData.dwCounter1 = -1;
1452     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1453                                     &callbackData, callbackData.dwFlags );
1454     check( 2, callbackData.dwCounter1 ); /* Both sessions automatically
1455                                             set DPSESSION_PASSWORDREQUIRED */
1456
1457     /* - Only session flag set */
1458     for (i=4; i<=5; i++)
1459     {
1460         IDirectPlayX_Release( pDPserver[i] );
1461         U2(dpsd_server[i]).lpszPasswordA = NULL;
1462     }
1463     dpsd_server[4].dwFlags = DPSESSION_PRIVATE;
1464     dpsd_server[5].dwFlags = DPSESSION_PASSWORDREQUIRED;
1465     for (i=4; i<=5; i++)
1466     {
1467         pDPserver[i] = create_session( &dpsd_server[i] );
1468     }
1469
1470     callbackData.dwFlags = 0;
1471     callbackData.dwCounter1 = -1;
1472     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1473                                     &callbackData, callbackData.dwFlags );
1474     check( 2, callbackData.dwCounter1 ); /* Without password,
1475                                             the flag is ignored */
1476
1477     /* - Both session flag and password set */
1478     for (i=4; i<=5; i++)
1479     {
1480         IDirectPlayX_Release( pDPserver[i] );
1481         U2(dpsd_server[i]).lpszPasswordA = (LPSTR) "password";
1482     }
1483     dpsd_server[4].dwFlags = DPSESSION_PRIVATE;
1484     dpsd_server[5].dwFlags = DPSESSION_PASSWORDREQUIRED;
1485     for (i=4; i<=5; i++)
1486     {
1487         pDPserver[i] = create_session( &dpsd_server[i] );
1488     }
1489
1490     /* - Listing without password */
1491     callbackData.dwCounter1 = -1;
1492     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1493                                     &callbackData, callbackData.dwFlags );
1494     check( 0, callbackData.dwCounter1 );
1495
1496     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1497     callbackData.dwCounter1 = -1;
1498     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1499                                     &callbackData, callbackData.dwFlags );
1500     check( 1, callbackData.dwCounter1 );
1501
1502     /* - Listing with incorrect password */
1503     U2(dpsd).lpszPasswordA = (LPSTR) "bad_password";
1504     callbackData.dwFlags = 0;
1505     callbackData.dwCounter1 = -1;
1506     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1507                                     &callbackData, callbackData.dwFlags );
1508     check( 0, callbackData.dwCounter1 );
1509
1510     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1511     callbackData.dwCounter1 = -1;
1512     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1513                                     &callbackData, callbackData.dwFlags );
1514     check( 1, callbackData.dwCounter1 );
1515
1516     /* - Listing with  correct password */
1517     U2(dpsd).lpszPasswordA = (LPSTR) "password";
1518     callbackData.dwCounter1 = -1;
1519     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1520                                     &callbackData, callbackData.dwFlags );
1521     check( 2, callbackData.dwCounter1 );
1522
1523
1524     U2(dpsd).lpszPasswordA = NULL;
1525     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1526     callbackData.dwCounter1 = -1;
1527     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1528                                     &callbackData, callbackData.dwFlags );
1529     check( 2, callbackData.dwCounter1 ); /* Read cache of last sync enumeration,
1530                                             even private sessions */
1531
1532
1533     /* GUID tests */
1534
1535     /* - Creating two servers with different application GUIDs */
1536     for (i=4; i<=5; i++)
1537     {
1538         IDirectPlayX_Release( pDPserver[i] );
1539         dpsd_server[i].dwFlags = ( DPSESSION_CLIENTSERVER |
1540                                    DPSESSION_DIRECTPLAYPROTOCOL );
1541         U2(dpsd_server[i]).lpszPasswordA = NULL;
1542         dpsd_server[i].dwMaxPlayers = 10;
1543     }
1544     U1(dpsd_server[4]).lpszSessionNameA = (LPSTR) "normal1";
1545     dpsd_server[4].guidApplication = appGuid;
1546     U1(dpsd_server[5]).lpszSessionNameA = (LPSTR) "normal2";
1547     dpsd_server[5].guidApplication = appGuid2;
1548     for (i=4; i<=5; i++)
1549     {
1550         pDPserver[i] = create_session( &dpsd_server[i] );
1551     }
1552
1553     callbackData.dwFlags = 0;
1554
1555     dpsd.guidApplication = appGuid2;
1556     callbackData.dwCounter1 = -1;
1557     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1558                                     &callbackData, callbackData.dwFlags );
1559     check( 1, callbackData.dwCounter1 ); /* Only one of the sessions */
1560
1561     dpsd.guidApplication = appGuid;
1562     callbackData.dwCounter1 = -1;
1563     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1564                                     &callbackData, callbackData.dwFlags );
1565     check( 1, callbackData.dwCounter1 ); /* The other session */
1566     /* FIXME:
1567        For some reason, if we enum 1st with appGuid and 2nd with appGuid2,
1568        in the second enum we get the 2 sessions. Dplay fault? Elves? */
1569
1570     dpsd.guidApplication = GUID_NULL;
1571     callbackData.dwCounter1 = -1;
1572     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1573                                     &callbackData, callbackData.dwFlags );
1574     check( 2, callbackData.dwCounter1 ); /* Both sessions */
1575
1576     for (i=4; i<=5; i++)
1577     {
1578         IDirectPlayX_Release( pDPserver[i] );
1579     }
1580     IDirectPlayX_Release( pDP );
1581
1582 }
1583
1584 /* SetSessionDesc
1585    GetSessionDesc */
1586
1587 static void test_SessionDesc(void)
1588 {
1589
1590     LPDIRECTPLAY4 pDP[2];
1591     DPSESSIONDESC2 dpsd;
1592     LPDPSESSIONDESC2 lpData[2];
1593     LPVOID lpDataMsg;
1594     DPID dpid[2];
1595     DWORD dwDataSize;
1596     HRESULT hr;
1597     UINT i;
1598     CallbackData callbackData;
1599
1600
1601     for (i=0; i<2; i++)
1602     {
1603         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1604                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
1605     }
1606     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1607
1608     /* Service provider not initialized */
1609     hr = IDirectPlayX_SetSessionDesc( pDP[0], NULL, 0 );
1610     checkHR( DPERR_UNINITIALIZED, hr );
1611
1612     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, NULL );
1613     checkHR( DPERR_UNINITIALIZED, hr );
1614
1615
1616     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
1617     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
1618
1619
1620     /* No sessions open */
1621     hr = IDirectPlayX_SetSessionDesc( pDP[0], NULL, 0 );
1622     todo_wine checkHR( DPERR_NOSESSIONS, hr );
1623
1624     if ( hr == DPERR_UNINITIALIZED )
1625     {
1626         todo_wine win_skip("Get/SetSessionDesc not implemented\n");
1627         return;
1628     }
1629
1630     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, NULL );
1631     checkHR( DPERR_NOSESSIONS, hr );
1632
1633
1634     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1635     dpsd.guidApplication = appGuid;
1636     dpsd.dwMaxPlayers = 10;
1637
1638
1639     /* Host */
1640     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1641     /* Peer */
1642     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
1643                                pDP[1], 0 );
1644
1645     for (i=0; i<2; i++)
1646     {
1647         /* Players, only to receive messages */
1648         IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL, 0, 0 );
1649
1650         lpData[i] = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
1651     }
1652     lpDataMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
1653
1654
1655     /* Incorrect parameters */
1656     hr = IDirectPlayX_SetSessionDesc( pDP[0], NULL, 0 );
1657     checkHR( DPERR_INVALIDPARAMS, hr );
1658     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, NULL );
1659     checkHR( DPERR_INVALIDPARAM, hr );
1660     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], NULL );
1661     checkHR( DPERR_INVALIDPARAM, hr );
1662     dwDataSize=-1;
1663     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1664     checkHR( DPERR_INVALIDPARAMS, hr );
1665     check( -1, dwDataSize );
1666
1667     /* Get: Insufficient buffer size */
1668     dwDataSize=0;
1669     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1670     checkHR( DPERR_BUFFERTOOSMALL, hr );
1671     check( dpsd.dwSize, dwDataSize );
1672     dwDataSize=4;
1673     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1674     checkHR( DPERR_BUFFERTOOSMALL, hr );
1675     check( dpsd.dwSize, dwDataSize );
1676     dwDataSize=1024;
1677     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, &dwDataSize );
1678     checkHR( DPERR_BUFFERTOOSMALL, hr );
1679     check( dpsd.dwSize, dwDataSize );
1680
1681     /* Get: Regular operation
1682      *  i=0: Local session
1683      *  i=1: Remote session */
1684     for (i=0; i<2; i++)
1685     {
1686         hr = IDirectPlayX_GetSessionDesc( pDP[i], lpData[i], &dwDataSize );
1687         checkHR( DP_OK, hr );
1688         check( sizeof(DPSESSIONDESC2), dwDataSize );
1689         check( sizeof(DPSESSIONDESC2), lpData[i]->dwSize );
1690         checkGuid( &appGuid, &lpData[i]->guidApplication );
1691         check( dpsd.dwMaxPlayers, lpData[i]->dwMaxPlayers );
1692     }
1693
1694     checkGuid( &lpData[0]->guidInstance, &lpData[1]->guidInstance );
1695
1696     /* Set: Regular operation */
1697     U1(dpsd).lpszSessionNameA = (LPSTR) "Wahaa";
1698     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1699     checkHR( DP_OK, hr );
1700
1701     dwDataSize = 1024;
1702     hr = IDirectPlayX_GetSessionDesc( pDP[1], lpData[1], &dwDataSize );
1703     checkHR( DP_OK, hr );
1704     checkStr( U1(dpsd).lpszSessionNameA, U1(*lpData[1]).lpszSessionNameA );
1705
1706
1707     /* Set: Failing to modify a remote session */
1708     hr = IDirectPlayX_SetSessionDesc( pDP[1], &dpsd, 0 );
1709     checkHR( DPERR_ACCESSDENIED, hr );
1710
1711     /* Trying to change inmutable properties */
1712     /*  Flags */
1713     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1714     checkHR( DP_OK, hr );
1715     dpsd.dwFlags = DPSESSION_SECURESERVER;
1716     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1717     checkHR( DPERR_INVALIDPARAMS, hr );
1718     dpsd.dwFlags = 0;
1719     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1720     checkHR( DP_OK, hr );
1721     /*  Size */
1722     dpsd.dwSize = 2048;
1723     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1724     checkHR( DPERR_INVALIDPARAMS, hr );
1725     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1726     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1727     checkHR( DP_OK, hr );
1728
1729     /* Changing the GUIDs and size is ignored */
1730     dpsd.guidApplication = appGuid2;
1731     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1732     checkHR( DP_OK, hr );
1733     dpsd.guidInstance = appGuid2;
1734     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1735     checkHR( DP_OK, hr );
1736
1737     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1738     checkHR( DP_OK, hr );
1739     checkGuid( &appGuid, &lpData[0]->guidApplication );
1740     checkGuid( &lpData[1]->guidInstance, &lpData[0]->guidInstance );
1741     check( sizeof(DPSESSIONDESC2), lpData[0]->dwSize );
1742
1743
1744     /* Checking system messages */
1745     check_messages( pDP[0], dpid, 2, &callbackData );
1746     checkStr( "S0,S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
1747     checkStr( "48,90,90,90,90,90,90,", callbackData.szTrace2 );
1748     check_messages( pDP[1], dpid, 2, &callbackData );
1749     checkStr( "S1,S1,S1,S1,S1,S1,", callbackData.szTrace1 );
1750     checkStr( "90,90,90,90,90,90,", callbackData.szTrace2 );
1751
1752     HeapFree( GetProcessHeap(), 0, lpDataMsg );
1753     for (i=0; i<2; i++)
1754     {
1755         HeapFree( GetProcessHeap(), 0, lpData[i] );
1756         IDirectPlayX_Release( pDP[i] );
1757     }
1758
1759 }
1760
1761 /* CreatePlayer */
1762
1763 static void test_CreatePlayer(void)
1764 {
1765
1766     LPDIRECTPLAY4 pDP[2];
1767     DPSESSIONDESC2 dpsd;
1768     DPNAME name;
1769     DPID dpid;
1770     HRESULT hr;
1771
1772
1773     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1774                       &IID_IDirectPlay4A, (LPVOID*) &pDP[0] );
1775     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1776                       &IID_IDirectPlay4A, (LPVOID*) &pDP[1] );
1777     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1778     ZeroMemory( &name, sizeof(DPNAME) );
1779
1780
1781     /* Connection not initialized */
1782     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL, 0, 0 );
1783     checkHR( DPERR_UNINITIALIZED, hr );
1784
1785
1786     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
1787     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
1788
1789
1790     /* Session not open */
1791     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL, 0, 0 );
1792     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1793
1794     if ( hr == DPERR_UNINITIALIZED )
1795     {
1796         todo_wine win_skip( "CreatePlayer not implemented\n" );
1797         return;
1798     }
1799
1800     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1801     dpsd.guidApplication = appGuid;
1802     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1803
1804
1805     /* Player name */
1806     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL, 0, 0 );
1807     checkHR( DP_OK, hr );
1808
1809
1810     name.dwSize = -1;
1811
1812
1813     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, &name, NULL, NULL, 0, 0 );
1814     checkHR( DP_OK, hr );
1815
1816
1817     name.dwSize = sizeof(DPNAME);
1818     U1(name).lpszShortNameA = (LPSTR) "test";
1819     U2(name).lpszLongNameA = NULL;
1820
1821
1822     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, &name, NULL, NULL,
1823                                     0, 0 );
1824     checkHR( DP_OK, hr );
1825
1826
1827     /* Null dpid */
1828     hr = IDirectPlayX_CreatePlayer( pDP[0], NULL, NULL, NULL, NULL,
1829                                     0, 0 );
1830     checkHR( DPERR_INVALIDPARAMS, hr );
1831
1832
1833     /* There can only be one server player */
1834     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1835                                     0, DPPLAYER_SERVERPLAYER );
1836     checkHR( DP_OK, hr );
1837     check( DPID_SERVERPLAYER, dpid );
1838
1839     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1840                                     0, DPPLAYER_SERVERPLAYER );
1841     checkHR( DPERR_CANTCREATEPLAYER, hr );
1842
1843     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1844
1845     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1846                                     0, DPPLAYER_SERVERPLAYER );
1847     checkHR( DP_OK, hr );
1848     check( DPID_SERVERPLAYER, dpid );
1849     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1850
1851
1852     /* Flags */
1853     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1854                                     0, 0 );
1855     checkHR( DP_OK, hr );
1856
1857     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1858                                     0, DPPLAYER_SERVERPLAYER );
1859     checkHR( DP_OK, hr );
1860     check( DPID_SERVERPLAYER, dpid );
1861     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1862
1863     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1864                                     0, DPPLAYER_SPECTATOR );
1865     checkHR( DP_OK, hr );
1866
1867     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1868                                     0, ( DPPLAYER_SERVERPLAYER |
1869                                          DPPLAYER_SPECTATOR ) );
1870     checkHR( DP_OK, hr );
1871     check( DPID_SERVERPLAYER, dpid );
1872     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1873
1874
1875     /* Session with DPSESSION_NEWPLAYERSDISABLED */
1876     IDirectPlayX_Close( pDP[0] );
1877     dpsd.dwFlags = DPSESSION_NEWPLAYERSDISABLED;
1878     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1879     checkHR( DP_OK, hr );
1880
1881
1882     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1883                                     0, 0 );
1884     checkHR( DPERR_CANTCREATEPLAYER, hr );
1885
1886     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1887                                     0, DPPLAYER_SERVERPLAYER );
1888     checkHR( DPERR_CANTCREATEPLAYER, hr );
1889
1890     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1891                                     0, DPPLAYER_SPECTATOR );
1892     checkHR( DPERR_CANTCREATEPLAYER, hr );
1893
1894
1895     /* Creating players in a Client/Server session */
1896     IDirectPlayX_Close( pDP[0] );
1897     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
1898     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1899     checkHR( DP_OK, hr );
1900     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
1901                                     pDP[1], 0 );
1902     checkHR( DP_OK, hr );
1903
1904
1905     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1906                                     0, 0 );
1907     checkHR( DPERR_ACCESSDENIED, hr );
1908
1909     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1910                                     0, DPPLAYER_SERVERPLAYER );
1911     checkHR( DP_OK, hr );
1912     check( DPID_SERVERPLAYER, dpid );
1913
1914     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid, NULL, NULL, NULL,
1915                                     0, DPPLAYER_SERVERPLAYER );
1916     checkHR( DPERR_INVALIDFLAGS, hr );
1917
1918     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid, NULL, NULL, NULL,
1919                                     0, 0 );
1920     checkHR( DP_OK, hr );
1921
1922
1923     IDirectPlayX_Release( pDP[0] );
1924     IDirectPlayX_Release( pDP[1] );
1925
1926 }
1927
1928 /* GetPlayerCaps */
1929
1930 static void test_GetPlayerCaps(void)
1931 {
1932
1933     LPDIRECTPLAY4 pDP[2];
1934     DPSESSIONDESC2 dpsd;
1935     DPID dpid[2];
1936     HRESULT hr;
1937     UINT i;
1938
1939     DPCAPS playerCaps;
1940     DWORD dwFlags;
1941
1942
1943     for (i=0; i<2; i++)
1944     {
1945         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1946                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
1947     }
1948     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1949     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1950     dpsd.guidApplication = appGuid;
1951     dpsd.dwMaxPlayers = 10;
1952
1953     ZeroMemory( &playerCaps, sizeof(DPCAPS) );
1954
1955
1956     /* Uninitialized service provider */
1957     playerCaps.dwSize = 0;
1958     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1959     checkHR( DPERR_UNINITIALIZED, hr );
1960
1961     playerCaps.dwSize = sizeof(DPCAPS);
1962     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1963     checkHR( DPERR_UNINITIALIZED, hr );
1964
1965
1966     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
1967     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
1968
1969
1970     /* No session */
1971     playerCaps.dwSize = 0;
1972
1973     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1974     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1975
1976     if ( hr == DPERR_UNINITIALIZED )
1977     {
1978         todo_wine win_skip( "GetPlayerCaps not implemented\n" );
1979         return;
1980     }
1981
1982     playerCaps.dwSize = sizeof(DPCAPS);
1983
1984     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1985     checkHR( DPERR_INVALIDPLAYER, hr );
1986
1987     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 2, &playerCaps, 0 );
1988     checkHR( DPERR_INVALIDPLAYER, hr );
1989
1990
1991     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1992     checkHR( DP_OK, hr );
1993     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
1994                                     pDP[1], 0 );
1995     checkHR( DP_OK, hr );
1996
1997     for (i=0; i<2; i++)
1998     {
1999         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
2000                                         NULL, NULL, NULL, 0, 0 );
2001         checkHR( DP_OK, hr );
2002     }
2003
2004
2005     /* Uninitialized playerCaps */
2006     playerCaps.dwSize = 0;
2007
2008     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
2009     checkHR( DPERR_INVALIDPARAMS, hr );
2010
2011     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 2, &playerCaps, 0 );
2012     checkHR( DPERR_INVALIDPARAMS, hr );
2013
2014     hr = IDirectPlayX_GetPlayerCaps( pDP[0], dpid[0], &playerCaps, 0 );
2015     checkHR( DPERR_INVALIDPARAMS, hr );
2016
2017
2018     /* Invalid player */
2019     playerCaps.dwSize = sizeof(DPCAPS);
2020
2021     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
2022     checkHR( DPERR_INVALIDPLAYER, hr );
2023
2024     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 2, &playerCaps, 0 );
2025     checkHR( DPERR_INVALIDPLAYER, hr );
2026
2027     hr = IDirectPlayX_GetPlayerCaps( pDP[0], dpid[0], &playerCaps, 0 );
2028     checkHR( DP_OK, hr );
2029
2030
2031     /* Regular parameters */
2032     for (i=0; i<2; i++)
2033     {
2034         for (dwFlags=0;
2035              dwFlags<=DPGETCAPS_GUARANTEED;
2036              dwFlags+=DPGETCAPS_GUARANTEED)
2037         {
2038
2039             hr = IDirectPlayX_GetPlayerCaps( pDP[0], dpid[i],
2040                                              &playerCaps, dwFlags );
2041             checkHR( DP_OK, hr );
2042
2043
2044             check( sizeof(DPCAPS), playerCaps.dwSize );
2045             check( 40,    playerCaps.dwSize );
2046             check( 0,     playerCaps.dwMaxQueueSize );
2047             check( 0,     playerCaps.dwHundredBaud );
2048             check( 0,     playerCaps.dwLatency );
2049             check( 65536, playerCaps.dwMaxLocalPlayers );
2050             check( 20,    playerCaps.dwHeaderLength );
2051
2052             if ( i == 0 )
2053             {
2054                 checkFlags( DPCAPS_ISHOST |
2055                             DPCAPS_GUARANTEEDOPTIMIZED |
2056                             DPCAPS_GUARANTEEDSUPPORTED |
2057                             DPCAPS_ASYNCSUPPORTED |
2058                             DPPLAYERCAPS_LOCAL,
2059                             playerCaps.dwFlags, FLAGS_DPCAPS );
2060             }
2061             else
2062                 checkFlags( DPCAPS_ISHOST |
2063                             DPCAPS_GUARANTEEDOPTIMIZED |
2064                             DPCAPS_GUARANTEEDSUPPORTED |
2065                             DPCAPS_ASYNCSUPPORTED,
2066                             playerCaps.dwFlags, FLAGS_DPCAPS );
2067
2068             if ( dwFlags == DPGETCAPS_GUARANTEED )
2069             {
2070                 check( 1048547, playerCaps.dwMaxBufferSize );
2071                 check( 64,      playerCaps.dwMaxPlayers );
2072             }
2073             else
2074             {
2075                 check( 65479, playerCaps.dwMaxBufferSize );
2076                 check( 65536, playerCaps.dwMaxPlayers );
2077             }
2078
2079         }
2080     }
2081
2082
2083     IDirectPlayX_Release( pDP[0] );
2084     IDirectPlayX_Release( pDP[1] );
2085
2086 }
2087
2088 /* SetPlayerData
2089    GetPlayerData */
2090
2091 static void test_PlayerData(void)
2092 {
2093     LPDIRECTPLAY4 pDP;
2094     DPSESSIONDESC2 dpsd;
2095     DPID dpid;
2096     HRESULT hr;
2097
2098     /* lpDataFake has to be bigger than the rest, limits lpDataGet size */
2099     LPCSTR lpDataFake     = "big_fake_data_chunk";
2100     DWORD dwDataSizeFake  = strlen(lpDataFake)+1;
2101
2102     LPCSTR lpData         = "remote_data";
2103     DWORD dwDataSize      = strlen(lpData)+1;
2104
2105     LPCSTR lpDataLocal    = "local_data";
2106     DWORD dwDataSizeLocal = strlen(lpDataLocal)+1;
2107
2108     LPSTR lpDataGet       = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
2109                                        dwDataSizeFake );
2110     DWORD dwDataSizeGet   = dwDataSizeFake;
2111
2112
2113     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2114                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
2115
2116     /* No service provider */
2117     hr = IDirectPlayX_SetPlayerData( pDP, 0, (LPVOID) lpData,
2118                                      dwDataSize, 0 );
2119     checkHR( DPERR_UNINITIALIZED, hr );
2120
2121     hr = IDirectPlayX_GetPlayerData( pDP, 0, lpDataGet, &dwDataSizeGet, 0 );
2122     checkHR( DPERR_UNINITIALIZED, hr );
2123
2124
2125     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
2126
2127     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2128     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2129     dpsd.guidApplication = appGuid;
2130     IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
2131
2132
2133     /* Invalid player */
2134     hr = IDirectPlayX_SetPlayerData( pDP, 0, (LPVOID) lpData,
2135                                      dwDataSize, 0 );
2136     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
2137
2138     hr = IDirectPlayX_GetPlayerData( pDP, 0, lpDataGet, &dwDataSizeGet, 0 );
2139     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
2140
2141     if ( hr == DPERR_UNINITIALIZED )
2142     {
2143         todo_wine win_skip( "Get/SetPlayerData not implemented\n" );
2144         return;
2145     }
2146
2147     /* Create the player */
2148     /* By default, the data is remote */
2149     hr = IDirectPlayX_CreatePlayer( pDP, &dpid, NULL, NULL, (LPVOID) lpData,
2150                                     dwDataSize, 0 );
2151     checkHR( DP_OK, hr );
2152
2153     /* Invalid parameters */
2154     hr = IDirectPlayX_SetPlayerData( pDP, dpid, NULL, dwDataSize, 0 );
2155     checkHR( DPERR_INVALIDPARAMS, hr );
2156     hr = IDirectPlayX_SetPlayerData( pDP, dpid, lpDataGet, -1, 0 );
2157     checkHR( DPERR_INVALIDPARAMS, hr );
2158
2159     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, NULL, 0 );
2160     checkHR( DPERR_INVALIDPARAMS, hr );
2161
2162
2163     /*
2164      * Remote data (default)
2165      */
2166
2167
2168     /* Buffer redimension */
2169     dwDataSizeGet = dwDataSizeFake;
2170     strcpy(lpDataGet, lpDataFake);
2171     hr = IDirectPlayX_GetPlayerData( pDP, dpid, NULL,
2172                                      &dwDataSizeGet, 0 );
2173     check( DPERR_BUFFERTOOSMALL, hr );
2174     check( dwDataSize, dwDataSizeGet );
2175     checkStr( lpDataFake, lpDataGet );
2176
2177     dwDataSizeGet = 2;
2178     strcpy(lpDataGet, lpDataFake);
2179     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2180     check( DPERR_BUFFERTOOSMALL, hr );
2181     check( dwDataSize, dwDataSizeGet );
2182
2183     strcpy(lpDataGet, lpDataFake);
2184     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2185     checkHR( DP_OK, hr );
2186     check( dwDataSize, dwDataSizeGet );
2187     checkStr( lpData, lpDataGet );
2188
2189     /* Normal operation */
2190     dwDataSizeGet = dwDataSizeFake;
2191     strcpy(lpDataGet, lpDataFake);
2192     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2193     checkHR( DP_OK, hr );
2194     check( dwDataSize, dwDataSizeGet );
2195     checkStr( lpData, lpDataGet );
2196
2197     /* Flag tests */
2198     dwDataSizeGet = dwDataSizeFake;
2199     strcpy(lpDataGet, lpDataFake);
2200     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2201     checkHR( DP_OK, hr );
2202     check( dwDataSize, dwDataSizeGet ); /* Remote: works as expected */
2203     checkStr( lpData, lpDataGet );
2204
2205     dwDataSizeGet = dwDataSizeFake;
2206     strcpy(lpDataGet, lpDataFake);
2207     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2208                                      DPGET_REMOTE );
2209     checkHR( DP_OK, hr );
2210     check( dwDataSize, dwDataSizeGet ); /* Same behaviour as in previous test */
2211     checkStr( lpData, lpDataGet );
2212
2213     dwDataSizeGet = dwDataSizeFake;
2214     strcpy(lpDataGet, lpDataFake);
2215     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2216                                      DPGET_LOCAL );
2217     checkHR( DP_OK, hr );
2218     check( 0, dwDataSizeGet ); /* Sets size to 0 (as local data doesn't exist) */
2219     checkStr( lpDataFake, lpDataGet );
2220
2221     dwDataSizeGet = dwDataSizeFake;
2222     strcpy(lpDataGet, lpDataFake);
2223     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2224                                      DPGET_LOCAL | DPGET_REMOTE );
2225     checkHR( DP_OK, hr );
2226     check( 0, dwDataSizeGet ); /* Same behaviour as in previous test */
2227     checkStr( lpDataFake, lpDataGet );
2228
2229     /* Getting local data (which doesn't exist), buffer size is ignored */
2230     dwDataSizeGet = 0;
2231     strcpy(lpDataGet, lpDataFake);
2232     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2233                                      DPGET_LOCAL );
2234     checkHR( DP_OK, hr );
2235     check( 0, dwDataSizeGet ); /* Sets size to 0 */
2236     checkStr( lpDataFake, lpDataGet );
2237
2238     dwDataSizeGet = dwDataSizeFake;
2239     strcpy(lpDataGet, lpDataFake);
2240     hr = IDirectPlayX_GetPlayerData( pDP, dpid, NULL, &dwDataSizeGet,
2241                                      DPGET_LOCAL );
2242     checkHR( DP_OK, hr );
2243     check( 0, dwDataSizeGet ); /* Sets size to 0 */
2244     checkStr( lpDataFake, lpDataGet );
2245
2246
2247     /*
2248      * Local data
2249      */
2250
2251
2252     /* Invalid flags */
2253     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2254                                      dwDataSizeLocal,
2255                                      DPSET_LOCAL | DPSET_GUARANTEED );
2256     checkHR( DPERR_INVALIDPARAMS, hr );
2257
2258     /* Correct parameters */
2259     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2260                                      dwDataSizeLocal, DPSET_LOCAL );
2261     checkHR( DP_OK, hr );
2262
2263     /* Flag tests (again) */
2264     dwDataSizeGet = dwDataSizeFake;
2265     strcpy(lpDataGet, lpDataFake);
2266     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2267     checkHR( DP_OK, hr );
2268     check( dwDataSize, dwDataSizeGet ); /* Remote: works as expected */
2269     checkStr( lpData, lpDataGet );
2270
2271     dwDataSizeGet = dwDataSizeFake;
2272     strcpy(lpDataGet, lpDataFake);
2273     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2274                                      DPGET_REMOTE );
2275     checkHR( DP_OK, hr );
2276     check( dwDataSize, dwDataSizeGet ); /* Like in previous test */
2277     checkStr( lpData, lpDataGet );
2278
2279     dwDataSizeGet = dwDataSizeFake;
2280     strcpy(lpDataGet, lpDataFake);
2281     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2282                                      DPGET_LOCAL );
2283     checkHR( DP_OK, hr );
2284     check( dwDataSizeLocal, dwDataSizeGet ); /* Local: works as expected */
2285     checkStr( lpDataLocal, lpDataGet );
2286
2287     dwDataSizeGet = dwDataSizeFake;
2288     strcpy(lpDataGet, lpDataFake);
2289     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2290                                      DPGET_LOCAL | DPGET_REMOTE );
2291     checkHR( DP_OK, hr );
2292     check( dwDataSizeLocal, dwDataSizeGet ); /* Like in previous test */
2293     checkStr( lpDataLocal, lpDataGet );
2294
2295     /* Small buffer works as expected again */
2296     dwDataSizeGet = 0;
2297     strcpy(lpDataGet, lpDataFake);
2298     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2299                                      DPGET_LOCAL );
2300     checkHR( DPERR_BUFFERTOOSMALL, hr );
2301     check( dwDataSizeLocal, dwDataSizeGet );
2302     checkStr( lpDataFake, lpDataGet );
2303
2304     dwDataSizeGet = dwDataSizeFake;
2305     strcpy(lpDataGet, lpDataFake);
2306     hr = IDirectPlayX_GetPlayerData( pDP, dpid, NULL,
2307                                      &dwDataSizeGet, DPGET_LOCAL );
2308     check( DPERR_BUFFERTOOSMALL, hr );
2309     check( dwDataSizeLocal, dwDataSizeGet );
2310     checkStr( lpDataFake, lpDataGet );
2311
2312
2313     /*
2314      * Changing remote data
2315      */
2316
2317
2318     /* Remote data := local data */
2319     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2320                                      dwDataSizeLocal,
2321                                      DPSET_GUARANTEED | DPSET_REMOTE );
2322     checkHR( DP_OK, hr );
2323     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2324                                      dwDataSizeLocal, 0 );
2325     checkHR( DP_OK, hr );
2326
2327     dwDataSizeGet = dwDataSizeFake;
2328     strcpy(lpDataGet, lpDataFake);
2329     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2330     checkHR( DP_OK, hr );
2331     check( dwDataSizeLocal, dwDataSizeGet );
2332     checkStr( lpDataLocal, lpDataGet );
2333
2334     /* Remote data := fake data */
2335     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataFake,
2336                                      dwDataSizeFake, DPSET_REMOTE );
2337     checkHR( DP_OK, hr );
2338
2339     dwDataSizeGet = dwDataSizeFake + 1;
2340     strcpy(lpDataGet, lpData);
2341     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2342     checkHR( DP_OK, hr );
2343     check( dwDataSizeFake, dwDataSizeGet );
2344     checkStr( lpDataFake, lpDataGet );
2345
2346
2347     HeapFree( GetProcessHeap(), 0, lpDataGet );
2348     IDirectPlayX_Release( pDP );
2349 }
2350
2351 /* GetPlayerName
2352    SetPlayerName */
2353
2354 static void test_PlayerName(void)
2355 {
2356
2357     LPDIRECTPLAY4 pDP[2];
2358     DPSESSIONDESC2 dpsd;
2359     DPID dpid[2];
2360     HRESULT hr;
2361     UINT i;
2362
2363     DPNAME playerName;
2364     DWORD dwDataSize = 1024;
2365     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2366     CallbackData callbackData;
2367
2368
2369     for (i=0; i<2; i++)
2370     {
2371         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2372                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2373     }
2374     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2375     ZeroMemory( &playerName, sizeof(DPNAME) );
2376
2377
2378     /* Service provider not initialized */
2379     hr = IDirectPlayX_SetPlayerName( pDP[0], 0, &playerName, 0 );
2380     checkHR( DPERR_UNINITIALIZED, hr );
2381
2382     dwDataSize = 1024;
2383     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2384     checkHR( DPERR_UNINITIALIZED, hr );
2385     check( 1024, dwDataSize );
2386
2387
2388     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2389     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2390
2391
2392     /* Session not initialized */
2393     hr = IDirectPlayX_SetPlayerName( pDP[0], 0, &playerName, 0 );
2394     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
2395
2396     if ( hr == DPERR_UNINITIALIZED )
2397     {
2398         todo_wine win_skip( "Get/SetPlayerName not implemented\n" );
2399         return;
2400     }
2401
2402     dwDataSize = 1024;
2403     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2404     checkHR( DPERR_INVALIDPLAYER, hr );
2405     check( 1024, dwDataSize );
2406
2407
2408     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2409     dpsd.guidApplication = appGuid;
2410     dpsd.dwMaxPlayers = 10;
2411     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2412     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2413                                pDP[1], 0 );
2414
2415     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
2416     IDirectPlayX_CreatePlayer( pDP[1], &dpid[1], NULL, NULL, NULL, 0, 0 );
2417
2418
2419     /* Name not initialized */
2420     playerName.dwSize = -1;
2421     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName, 0 );
2422     checkHR( DP_OK, hr );
2423
2424     dwDataSize = 1024;
2425     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2426     checkHR( DPERR_INVALIDPLAYER, hr );
2427     check( 1024, dwDataSize );
2428
2429
2430     playerName.dwSize = sizeof(DPNAME);
2431     U1(playerName).lpszShortNameA = (LPSTR) "player_name";
2432     U2(playerName).lpszLongNameA = (LPSTR) "player_long_name";
2433
2434
2435     /* Invalid parameters */
2436     hr = IDirectPlayX_SetPlayerName( pDP[0], -1, &playerName, 0 );
2437     checkHR( DPERR_INVALIDPLAYER, hr );
2438     hr = IDirectPlayX_SetPlayerName( pDP[0], 0, &playerName, 0 );
2439     checkHR( DPERR_INVALIDPLAYER, hr );
2440     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName, -1 );
2441     checkHR( DPERR_INVALIDPARAMS, hr );
2442
2443     dwDataSize = 1024;
2444     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2445     checkHR( DPERR_INVALIDPLAYER, hr );
2446     check( 1024, dwDataSize );
2447
2448     dwDataSize = -1;
2449     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2450     checkHR( DPERR_INVALIDPARAMS, hr );
2451     check( -1, dwDataSize );
2452
2453     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, NULL );
2454     checkHR( DPERR_INVALIDPARAMS, hr );
2455
2456     /* Trying to modify remote player */
2457     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[1], &playerName, 0 );
2458     checkHR( DPERR_ACCESSDENIED, hr );
2459
2460
2461     /* Regular operation */
2462     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName, 0 );
2463
2464     dwDataSize = 1024;
2465     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2466     checkHR( DP_OK, hr );
2467     check( 45, dwDataSize );
2468     checkStr( U1(playerName).lpszShortNameA, U1(*(LPDPNAME)lpData).lpszShortNameA );
2469     checkStr( U2(playerName).lpszLongNameA,  U2(*(LPDPNAME)lpData).lpszLongNameA );
2470     check( 0,                            ((LPDPNAME)lpData)->dwFlags );
2471
2472     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], NULL, 0 );
2473
2474     dwDataSize = 1024;
2475     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2476     checkHR( DP_OK, hr );
2477     check( 16, dwDataSize );
2478     checkLP( NULL, U1(*(LPDPNAME)lpData).lpszShortNameA );
2479     checkLP( NULL, U2(*(LPDPNAME)lpData).lpszLongNameA );
2480     check( 0,      ((LPDPNAME)lpData)->dwFlags );
2481
2482
2483     /* Small buffer in get operation */
2484     dwDataSize = 1024;
2485     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], NULL, &dwDataSize );
2486     checkHR( DPERR_BUFFERTOOSMALL, hr );
2487     check( 16, dwDataSize );
2488
2489     dwDataSize = 0;
2490     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2491     checkHR( DPERR_BUFFERTOOSMALL, hr );
2492     check( 16, dwDataSize );
2493
2494     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2495     checkHR( DP_OK, hr );
2496     check( 16, dwDataSize );
2497     checkLP( NULL, U1(*(LPDPNAME)lpData).lpszShortNameA );
2498     checkLP( NULL, U2(*(LPDPNAME)lpData).lpszLongNameA );
2499     check( 0, ((LPDPNAME)lpData)->dwFlags );
2500
2501
2502     /* Flags */
2503     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2504                                      DPSET_GUARANTEED );
2505     checkHR( DP_OK, hr );
2506
2507     /* - Local (no propagation) */
2508     U1(playerName).lpszShortNameA = (LPSTR) "no_propagation";
2509     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2510                                      DPSET_LOCAL );
2511     checkHR( DP_OK, hr );
2512
2513     dwDataSize = 1024;
2514     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0],
2515                                      lpData, &dwDataSize ); /* Local fetch */
2516     checkHR( DP_OK, hr );
2517     check( 48, dwDataSize );
2518     checkStr( "no_propagation", U1(*(LPDPNAME)lpData).lpszShortNameA );
2519
2520     dwDataSize = 1024;
2521     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2522                                      lpData, &dwDataSize ); /* Remote fetch */
2523     checkHR( DP_OK, hr );
2524     check( 45, dwDataSize );
2525     checkStr( "player_name", U1(*(LPDPNAME)lpData).lpszShortNameA );
2526
2527     /* -- 2 */
2528
2529     U1(playerName).lpszShortNameA = (LPSTR) "no_propagation_2";
2530     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2531                                      DPSET_LOCAL | DPSET_REMOTE );
2532     checkHR( DP_OK, hr );
2533
2534     dwDataSize = 1024;
2535     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0],
2536                                      lpData, &dwDataSize ); /* Local fetch */
2537     checkHR( DP_OK, hr );
2538     check( 50, dwDataSize );
2539     checkStr( "no_propagation_2", U1(*(LPDPNAME)lpData).lpszShortNameA );
2540
2541     dwDataSize = 1024;
2542     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2543                                      lpData, &dwDataSize ); /* Remote fetch */
2544     checkHR( DP_OK, hr );
2545     check( 45, dwDataSize );
2546     checkStr( "player_name", U1(*(LPDPNAME)lpData).lpszShortNameA );
2547
2548     /* - Remote (propagation, default) */
2549     U1(playerName).lpszShortNameA = (LPSTR) "propagation";
2550     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2551                                      DPSET_REMOTE );
2552     checkHR( DP_OK, hr );
2553
2554     dwDataSize = 1024;
2555     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2556                                      lpData, &dwDataSize ); /* Remote fetch */
2557     checkHR( DP_OK, hr );
2558     check( 45, dwDataSize );
2559     checkStr( "propagation", U1(*(LPDPNAME)lpData).lpszShortNameA );
2560
2561     /* -- 2 */
2562     U1(playerName).lpszShortNameA = (LPSTR) "propagation_2";
2563     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2564                                      0 );
2565     checkHR( DP_OK, hr );
2566
2567     dwDataSize = 1024;
2568     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2569                                      lpData, &dwDataSize ); /* Remote fetch */
2570     checkHR( DP_OK, hr );
2571     check( 47, dwDataSize );
2572     checkStr( "propagation_2", U1(*(LPDPNAME)lpData).lpszShortNameA );
2573
2574
2575     /* Checking system messages */
2576     check_messages( pDP[0], dpid, 2, &callbackData );
2577     checkStr( "S0,S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
2578     checkStr( "48,28,57,28,57,57,59,", callbackData.szTrace2 );
2579     check_messages( pDP[1], dpid, 2, &callbackData );
2580     checkStr( "S1,S1,S1,S1,S1,S1,", callbackData.szTrace1 );
2581     checkStr( "28,57,28,57,57,59,", callbackData.szTrace2 );
2582
2583
2584     HeapFree( GetProcessHeap(), 0, lpData );
2585     IDirectPlayX_Release( pDP[0] );
2586     IDirectPlayX_Release( pDP[1] );
2587
2588 }
2589
2590 /* GetPlayerAccount */
2591
2592 static BOOL CALLBACK EnumSessions_cb_join_secure( LPCDPSESSIONDESC2 lpThisSD,
2593                                                   LPDWORD lpdwTimeOut,
2594                                                   DWORD dwFlags,
2595                                                   LPVOID lpContext )
2596 {
2597     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
2598     DPSESSIONDESC2 dpsd;
2599     DPCREDENTIALS dpCredentials;
2600     HRESULT hr;
2601
2602     if (dwFlags & DPESC_TIMEDOUT)
2603     {
2604         return FALSE;
2605     }
2606
2607     checkFlags( DPSESSION_SECURESERVER, lpThisSD->dwFlags, FLAGS_DPSESSION );
2608
2609     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2610     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2611     dpsd.guidApplication = appGuid;
2612     dpsd.guidInstance = lpThisSD->guidInstance;
2613
2614     ZeroMemory( &dpCredentials, sizeof(DPCREDENTIALS) );
2615     dpCredentials.dwSize = sizeof(DPCREDENTIALS);
2616     U1(dpCredentials).lpszUsernameA = (LPSTR) "user";
2617     U2(dpCredentials).lpszPasswordA = (LPSTR) "pass";
2618     hr = IDirectPlayX_SecureOpen( pDP, &dpsd, DPOPEN_JOIN,
2619                                   NULL, &dpCredentials );
2620     checkHR( DPERR_LOGONDENIED, hr ); /* TODO: Make this work */
2621
2622     return TRUE;
2623 }
2624
2625 static void test_GetPlayerAccount(void)
2626 {
2627
2628     LPDIRECTPLAY4 pDP[2];
2629     DPSESSIONDESC2 dpsd;
2630     DPID dpid[2];
2631     HRESULT hr;
2632     UINT i;
2633
2634     DWORD dwDataSize = 1024;
2635     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2636
2637
2638     for (i=0; i<2; i++)
2639     {
2640         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2641                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2642     }
2643     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2644     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2645     dpsd.guidApplication = appGuid;
2646     dpsd.dwMaxPlayers = 10;
2647
2648     /* Uninitialized service provider */
2649     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0, lpData, &dwDataSize );
2650     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2651
2652     if ( hr == DP_OK )
2653     {
2654         todo_wine win_skip( "GetPlayerAccount not implemented\n" );
2655         return;
2656     }
2657
2658
2659     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2660     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2661
2662
2663     /* No session */
2664     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0, lpData, &dwDataSize );
2665     checkHR( DPERR_NOSESSIONS, hr );
2666
2667
2668     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2669     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2670                                pDP[1], 0 );
2671
2672     for (i=0; i<2; i++)
2673     {
2674         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL,
2675                                         0, 0 );
2676         checkHR( DP_OK, hr );
2677     }
2678
2679
2680     /* Session is not secure */
2681     dwDataSize = 1024;
2682     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2683                                         lpData, &dwDataSize );
2684     checkHR( DPERR_UNSUPPORTED, hr );
2685     check( 1024, dwDataSize );
2686
2687
2688     /* Open a secure session */
2689     for (i=0; i<2; i++)
2690     {
2691         hr = IDirectPlayX_Close( pDP[i] );
2692         checkHR( DP_OK, hr );
2693     }
2694
2695     dpsd.dwFlags = DPSESSION_SECURESERVER;
2696     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
2697     checkHR( DP_OK, hr );
2698
2699     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
2700                                     NULL, NULL, NULL, 0, 0 );
2701     checkHR( DP_OK, hr );
2702
2703     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0,
2704                                     EnumSessions_cb_join_secure, pDP[1], 0 );
2705     checkHR( DP_OK, hr );
2706
2707     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
2708                                     NULL, NULL, NULL, 0, 0 );
2709     checkHR( DPERR_INVALIDPARAMS, hr );
2710
2711     /* TODO: Player creation so that this works */
2712
2713     /* Invalid player */
2714     dwDataSize = 1024;
2715     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0,
2716                                         lpData, &dwDataSize );
2717     checkHR( DPERR_INVALIDPLAYER, hr );
2718     check( 1024, dwDataSize );
2719
2720     /* Invalid flags */
2721     dwDataSize = 1024;
2722     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], -1,
2723                                         lpData, &dwDataSize );
2724     checkHR( DPERR_INVALIDFLAGS, hr );
2725     check( 1024, dwDataSize );
2726
2727     dwDataSize = 1024;
2728     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 1,
2729                                         lpData, &dwDataSize );
2730     checkHR( DPERR_INVALIDFLAGS, hr );
2731     check( 1024, dwDataSize );
2732
2733     /* Small buffer */
2734     dwDataSize = 1024;
2735     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2736                                         NULL, &dwDataSize );
2737     checkHR( DPERR_INVALIDPLAYER, hr );
2738     check( 0, dwDataSize );
2739
2740     dwDataSize = 0;
2741     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2742                                         lpData, &dwDataSize );
2743     checkHR( DPERR_INVALIDPLAYER, hr );
2744     check( 0, dwDataSize );
2745
2746     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2747                                         lpData, &dwDataSize );
2748     checkHR( DPERR_INVALIDPLAYER, hr );
2749     check( 0, dwDataSize );
2750
2751     /* Normal operation */
2752     dwDataSize = 1024;
2753     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2754                                         lpData, &dwDataSize );
2755     checkHR( DPERR_INVALIDPLAYER, hr );
2756     check( 1024, dwDataSize );
2757
2758
2759     HeapFree( GetProcessHeap(), 0, lpData );
2760     IDirectPlayX_Release( pDP[0] );
2761     IDirectPlayX_Release( pDP[1] );
2762
2763 }
2764
2765 /* GetPlayerAddress */
2766
2767 static BOOL CALLBACK EnumAddress_cb( REFGUID guidDataType,
2768                                      DWORD dwDataSize,
2769                                      LPCVOID lpData,
2770                                      LPVOID lpContext )
2771 {
2772     lpCallbackData callbackData = (lpCallbackData) lpContext;
2773     static REFGUID types[] = { &DPAID_TotalSize,
2774                                &DPAID_ServiceProvider,
2775                                &DPAID_INet,
2776                                &DPAID_INetW };
2777     static DWORD sizes[] = { 4, 16, 12, 24, 4, 16, 10, 20 };
2778
2779
2780     checkGuid( types[callbackData->dwCounter1%4], guidDataType );
2781     check( sizes[callbackData->dwCounter1], dwDataSize );
2782
2783     switch(callbackData->dwCounter1)
2784     {
2785     case 0:
2786         check( 136, *(LPDWORD) lpData );
2787         break;
2788     case 4:
2789         check( 130, *(LPDWORD) lpData );
2790         break;
2791     case 1:
2792     case 5:
2793         checkGuid( &DPSPGUID_TCPIP, lpData );
2794         break;
2795     case 6:
2796         checkStr( "127.0.0.1", (LPSTR) lpData );
2797         break;
2798     default: break;
2799     }
2800
2801
2802     callbackData->dwCounter1++;
2803
2804     return TRUE;
2805 }
2806
2807 static void test_GetPlayerAddress(void)
2808 {
2809
2810     LPDIRECTPLAY4 pDP[2];
2811     LPDIRECTPLAYLOBBY3 pDPL;
2812     DPSESSIONDESC2 dpsd;
2813     DPID dpid[2];
2814     CallbackData callbackData;
2815     HRESULT hr;
2816     UINT i;
2817
2818     DWORD dwDataSize = 1024;
2819     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2820
2821
2822     for (i=0; i<2; i++)
2823     {
2824         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2825                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2826     }
2827     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2828     CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
2829                       &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
2830
2831
2832     /* Uninitialized service provider */
2833     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0, lpData, &dwDataSize );
2834     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2835
2836     if ( hr == DP_OK )
2837     {
2838         todo_wine win_skip( "GetPlayerAddress not implemented\n" );
2839         return;
2840     }
2841
2842     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2843     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2844
2845
2846     /* No session */
2847     dwDataSize = 1024;
2848     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0, lpData, &dwDataSize );
2849     checkHR( DPERR_UNSUPPORTED, hr );
2850     check( 1024, dwDataSize );
2851
2852     dwDataSize = 1024;
2853     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 1, lpData, &dwDataSize );
2854     checkHR( DPERR_INVALIDPLAYER, hr );
2855     check( 1024, dwDataSize );
2856
2857
2858     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2859     dpsd.guidApplication = appGuid;
2860     dpsd.dwMaxPlayers = 10;
2861     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2862     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2863                                pDP[1], 0 );
2864
2865     for (i=0; i<2; i++)
2866     {
2867         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL,
2868                                         0, 0 );
2869         checkHR( DP_OK, hr );
2870     }
2871
2872     /* Invalid player */
2873     dwDataSize = 1024;
2874     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0,
2875                                         lpData, &dwDataSize );
2876     checkHR( DPERR_UNSUPPORTED, hr );
2877     check( 1024, dwDataSize );
2878
2879     dwDataSize = 1024;
2880     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 1,
2881                                         lpData, &dwDataSize );
2882     checkHR( DPERR_INVALIDPLAYER, hr );
2883     check( 1024, dwDataSize );
2884
2885     /* Small buffer */
2886     dwDataSize = 1024;
2887     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2888                                         NULL, &dwDataSize );
2889     checkHR( DPERR_BUFFERTOOSMALL, hr );
2890     check( 136, dwDataSize );
2891
2892     dwDataSize = 0;
2893     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2894                                         lpData, &dwDataSize );
2895     checkHR( DPERR_BUFFERTOOSMALL, hr );
2896     check( 136, dwDataSize );
2897
2898     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2899                                         lpData, &dwDataSize );
2900     checkHR( DP_OK, hr );
2901     check( 136, dwDataSize );
2902
2903
2904     /* Regular parameters */
2905     callbackData.dwCounter1 = 0;
2906
2907     /* - Local */
2908     dwDataSize = 1024;
2909     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2910                                         lpData, &dwDataSize );
2911     checkHR( DP_OK, hr );
2912     check( 136, dwDataSize );
2913
2914     hr = IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb, lpData, dwDataSize,
2915                                        &callbackData );
2916     checkHR( DP_OK, hr );
2917
2918     check( 4, callbackData.dwCounter1 );
2919
2920     /* - Remote */
2921     dwDataSize = 1024;
2922     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[1],
2923                                         lpData, &dwDataSize );
2924     checkHR( DP_OK, hr );
2925     check( 130, dwDataSize );
2926
2927     hr = IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb, lpData, dwDataSize,
2928                                        &callbackData );
2929     checkHR( DP_OK, hr );
2930
2931     check( 8, callbackData.dwCounter1 );
2932
2933
2934     HeapFree( GetProcessHeap(), 0, lpData );
2935     IDirectPlayX_Release( pDP[0] );
2936     IDirectPlayX_Release( pDP[1] );
2937
2938 }
2939
2940 /* GetPlayerFlags */
2941
2942 static void test_GetPlayerFlags(void)
2943 {
2944
2945     LPDIRECTPLAY4 pDP[2];
2946     DPSESSIONDESC2 dpsd;
2947     DPID dpid[4];
2948     HRESULT hr;
2949     UINT i;
2950
2951     DWORD dwFlags = 0;
2952
2953
2954     for (i=0; i<2; i++)
2955     {
2956         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2957                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2958     }
2959     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2960     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2961     dpsd.guidApplication = appGuid;
2962     dpsd.dwMaxPlayers = 10;
2963
2964     /* Uninitialized service provider */
2965     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
2966     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2967
2968     if ( hr == DP_OK )
2969     {
2970         todo_wine win_skip( "GetPlayerFlags not implemented\n" );
2971         return;
2972     }
2973
2974     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2975     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2976
2977
2978     /* No session */
2979     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
2980     checkHR( DPERR_INVALIDPLAYER, hr );
2981
2982     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 1, &dwFlags );
2983     checkHR( DPERR_INVALIDPLAYER, hr );
2984
2985
2986     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2987     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2988                                pDP[1], 0 );
2989
2990     for (i=0; i<2; i++)
2991     {
2992         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
2993                                         NULL, NULL, NULL, 0, 0 );
2994         checkHR( DP_OK, hr );
2995     }
2996     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[2],
2997                                     NULL, NULL, NULL,
2998                                     0, DPPLAYER_SPECTATOR );
2999     checkHR( DP_OK, hr );
3000     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[3],
3001                                     NULL, NULL, NULL,
3002                                     0, DPPLAYER_SERVERPLAYER );
3003     checkHR( DP_OK, hr );
3004
3005
3006     /* Invalid player */
3007     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
3008     checkHR( DPERR_INVALIDPLAYER, hr );
3009
3010     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 2, &dwFlags );
3011     checkHR( DPERR_INVALIDPLAYER, hr );
3012
3013     /* Invalid parameters */
3014     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[0], NULL );
3015     checkHR( DPERR_INVALIDPARAMS, hr );
3016
3017
3018     /* Regular parameters */
3019     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[0], &dwFlags );
3020     checkHR( DP_OK, hr );
3021     checkFlags( dwFlags, DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3022
3023     hr = IDirectPlayX_GetPlayerFlags( pDP[1], dpid[1], &dwFlags );
3024     checkHR( DP_OK, hr );
3025     checkFlags( dwFlags, DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3026
3027     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[1], &dwFlags );
3028     checkHR( DP_OK, hr );
3029     checkFlags( dwFlags, 0, FLAGS_DPPLAYER );
3030
3031     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[2], &dwFlags );
3032     checkHR( DP_OK, hr );
3033     checkFlags( dwFlags, DPPLAYER_SPECTATOR | DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3034
3035     hr = IDirectPlayX_GetPlayerFlags( pDP[1], dpid[3], &dwFlags );
3036     checkHR( DP_OK, hr );
3037     checkFlags( dwFlags, DPPLAYER_SERVERPLAYER, FLAGS_DPPLAYER );
3038
3039
3040     IDirectPlayX_Release( pDP[0] );
3041     IDirectPlayX_Release( pDP[1] );
3042
3043 }
3044
3045 /* CreateGroup
3046    CreateGroupInGroup */
3047
3048 static void test_CreateGroup(void)
3049 {
3050
3051     LPDIRECTPLAY4 pDP;
3052     DPSESSIONDESC2 dpsd;
3053     DPID idFrom, idTo, dpid, idGroup, idGroupParent;
3054     DPNAME groupName;
3055     HRESULT hr;
3056     UINT i;
3057
3058     LPCSTR lpData = "data";
3059     DWORD dwDataSize = strlen(lpData)+1;
3060     LPDPMSG_CREATEPLAYERORGROUP lpDataGet = HeapAlloc( GetProcessHeap(),
3061                                                        HEAP_ZERO_MEMORY,
3062                                                        1024 );
3063     DWORD dwDataSizeGet = 1024;
3064     CallbackData callbackData;
3065
3066
3067     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3068                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
3069     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
3070     dpsd.dwSize = sizeof(DPSESSIONDESC2);
3071     dpsd.guidApplication = appGuid;
3072     dpsd.dwMaxPlayers = 10;
3073     ZeroMemory( &groupName, sizeof(DPNAME) );
3074
3075
3076     /* No service provider */
3077     hr = IDirectPlayX_CreateGroup( pDP, &idGroup, NULL, NULL, 0, 0 );
3078     checkHR( DPERR_UNINITIALIZED, hr );
3079
3080     hr = IDirectPlayX_CreateGroupInGroup( pDP, 0, &idGroup, NULL, NULL, 0, 0 );
3081     checkHR( DPERR_UNINITIALIZED, hr );
3082
3083
3084
3085     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
3086
3087
3088     /* No session */
3089     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3090                                    NULL, NULL, 0, 0 );
3091     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
3092
3093     if ( hr == DPERR_UNINITIALIZED )
3094     {
3095         todo_wine win_skip( "CreateGroup not implemented\n" );
3096         return;
3097     }
3098
3099     hr = IDirectPlayX_CreateGroupInGroup( pDP, 0, &idGroup,
3100                                           NULL, NULL, 0, 0 );
3101     checkHR( DPERR_INVALIDGROUP, hr );
3102
3103     hr = IDirectPlayX_CreateGroupInGroup( pDP, 2, &idGroup,
3104                                           NULL, NULL, 0, 0 );
3105     checkHR( DPERR_INVALIDGROUP, hr );
3106
3107
3108     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3109     checkHR( DP_OK, hr );
3110     IDirectPlayX_CreatePlayer( pDP, &dpid,
3111                                NULL, NULL, NULL, 0, 0 );
3112
3113
3114
3115     /* With name */
3116     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3117                                    NULL, NULL, 0, 0 );
3118     checkHR( DP_OK, hr );
3119
3120     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3121                                           NULL, NULL, 0, 0 );
3122     checkHR( DP_OK, hr );
3123
3124     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3125                                    &groupName, NULL, 0, 0 );
3126     checkHR( DP_OK, hr );
3127
3128     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3129                                           &groupName, NULL, 0, 0 );
3130     checkHR( DP_OK, hr );
3131
3132
3133     groupName.dwSize = sizeof(DPNAME);
3134     U1(groupName).lpszShortNameA = (LPSTR) lpData;
3135
3136
3137     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3138                                    &groupName, NULL, 0, 0 );
3139     checkHR( DP_OK, hr );
3140
3141     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3142                                           &groupName, NULL, 0, 0 );
3143     checkHR( DP_OK, hr );
3144
3145
3146     /* Message checking */
3147     for (i=0; i<6; i++)
3148     {
3149         dwDataSizeGet = 1024;
3150         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3151                                    &dwDataSizeGet );
3152         checkHR( DP_OK, hr );
3153         if ( NULL == U1(lpDataGet->dpnName).lpszShortNameA )
3154         {
3155             check( 48, dwDataSizeGet );
3156         }
3157         else
3158         {
3159             check( 48 + dwDataSize, dwDataSizeGet );
3160             checkStr( lpData, U1(lpDataGet->dpnName).lpszShortNameA );
3161         }
3162         check( DPID_SYSMSG, idFrom );
3163         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3164         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3165         checkFlags( DPGROUP_LOCAL,            lpDataGet->dwFlags, FLAGS_DPGROUP );
3166     }
3167     check_messages( pDP, &dpid, 1, &callbackData );
3168     checkStr( "", callbackData.szTrace1 );
3169
3170
3171     /* With data */
3172     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3173                                    NULL, (LPVOID) lpData, -1, 0 );
3174     checkHR( DPERR_INVALIDPARAMS, hr );
3175
3176     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3177                                    NULL, (LPVOID) lpData, 0, 0 );
3178     checkHR( DP_OK, hr );
3179
3180     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3181                                    NULL, NULL, dwDataSize, 0 );
3182     checkHR( DPERR_INVALIDPARAMS, hr );
3183
3184     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3185                                    NULL, (LPVOID) lpData, dwDataSize, 0 );
3186     checkHR( DP_OK, hr );
3187
3188
3189     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3190                                           NULL, (LPVOID) lpData, -1, 0 );
3191     checkHR( DPERR_INVALIDPARAMS, hr );
3192
3193     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3194                                           NULL, (LPVOID) lpData, 0, 0 );
3195     checkHR( DP_OK, hr );
3196
3197     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3198                                           NULL, NULL, dwDataSize, 0 );
3199     checkHR( DPERR_INVALIDPARAMS, hr );
3200
3201     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3202                                           NULL, (LPVOID)lpData, dwDataSize, 0 );
3203     checkHR( DP_OK, hr );
3204
3205
3206     hr = IDirectPlayX_CreateGroup( pDP, &idGroupParent,
3207                                    NULL, NULL, 0, 0 );
3208     checkHR( DP_OK, hr );
3209
3210
3211     /* Message checking */
3212     for (i=0; i<5; i++)
3213     {
3214         dwDataSizeGet = 1024;
3215         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3216                                    &dwDataSizeGet );
3217         checkHR( DP_OK, hr );
3218         check( 48 + lpDataGet->dwDataSize, dwDataSizeGet );
3219         check( DPID_SYSMSG, idFrom );
3220         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3221         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3222         checkFlags( DPGROUP_LOCAL,            lpDataGet->dwFlags, FLAGS_DPGROUP );
3223     }
3224     check_messages( pDP, &dpid, 1, &callbackData );
3225     checkStr( "", callbackData.szTrace1 );
3226
3227
3228     /* Flags and idGroupParent */
3229     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3230                                    NULL, NULL, 0, 0 );
3231     checkHR( DP_OK, hr );
3232
3233     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3234                                    NULL, NULL, 0, DPGROUP_HIDDEN );
3235     checkHR( DP_OK, hr );
3236
3237     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3238                                    NULL, NULL, 0, DPGROUP_STAGINGAREA );
3239     checkHR( DP_OK, hr );
3240
3241     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3242                                    NULL, NULL, 0,
3243                                    DPGROUP_HIDDEN | DPGROUP_STAGINGAREA );
3244     checkHR( DP_OK, hr );
3245
3246
3247     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3248                                           NULL, NULL, 0, 0 );
3249     checkHR( DP_OK, hr );
3250
3251     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3252                                           NULL, NULL, 0, DPGROUP_HIDDEN );
3253     checkHR( DP_OK, hr );
3254
3255     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3256                                           NULL, NULL, 0, DPGROUP_STAGINGAREA );
3257     checkHR( DP_OK, hr );
3258
3259     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3260                                           NULL, NULL, 0,
3261                                           DPGROUP_HIDDEN |
3262                                           DPGROUP_STAGINGAREA );
3263     checkHR( DP_OK, hr );
3264
3265
3266     /* Message checking */
3267     for (i=0; i<8; i++)
3268     {
3269         dwDataSizeGet = 1024;
3270         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3271                                    &dwDataSizeGet );
3272         checkHR( DP_OK, hr );
3273         check( 48, dwDataSizeGet );
3274         check( DPID_SYSMSG, idFrom );
3275         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3276         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3277
3278         if ( lpDataGet->dpIdParent != 0 )
3279         {
3280             check( idGroupParent, lpDataGet->dpIdParent );
3281         }
3282
3283         switch (i%4)
3284         {
3285         case 0:
3286             checkFlags( DPGROUP_LOCAL,
3287                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3288             break;
3289         case 1:
3290             checkFlags( DPGROUP_LOCAL | DPGROUP_HIDDEN,
3291                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3292             break;
3293         case 2:
3294             checkFlags( DPGROUP_STAGINGAREA | DPGROUP_LOCAL,
3295                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3296             break;
3297         case 3:
3298             checkFlags( DPGROUP_STAGINGAREA | DPGROUP_LOCAL | DPGROUP_HIDDEN,
3299                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3300             break;
3301         default: break;
3302         }
3303     }
3304     check_messages( pDP, &dpid, 1, &callbackData );
3305     checkStr( "", callbackData.szTrace1 );
3306
3307
3308     /* If a group is created in C/S mode, no messages are sent */
3309
3310     /* - Peer 2 peer */
3311     IDirectPlayX_Close( pDP );
3312
3313     dpsd.dwFlags = 0;
3314     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3315     checkHR( DP_OK, hr );
3316     hr = IDirectPlayX_CreatePlayer( pDP, &dpid, NULL, NULL, NULL, 0, 0 );
3317     checkHR( DP_OK, hr );
3318
3319     hr = IDirectPlayX_CreateGroup( pDP, &idGroup, NULL, NULL, 0, 0 );
3320     checkHR( DP_OK, hr );
3321
3322     /* Messages are received */
3323     check_messages( pDP, &dpid, 1, &callbackData );
3324     checkStr( "S0,", callbackData.szTrace1 );
3325
3326
3327     /* - Client/Server */
3328     IDirectPlayX_Close( pDP );
3329
3330     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
3331     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3332     checkHR( DP_OK, hr );
3333     hr = IDirectPlayX_CreatePlayer( pDP, &dpid,
3334                                     NULL, NULL, NULL, 0,
3335                                     DPPLAYER_SERVERPLAYER );
3336     checkHR( DP_OK, hr );
3337
3338     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3339                                    NULL, NULL, 0, 0 );
3340     checkHR( DP_OK, hr );
3341
3342     /* No messages */
3343     check_messages( pDP, &dpid, 1, &callbackData );
3344     checkStr( "S0,", callbackData.szTrace1 ); /* Or at least there
3345                                                  shouldn't be messages... */
3346
3347
3348     HeapFree( GetProcessHeap(), 0, lpDataGet );
3349     IDirectPlayX_Release( pDP );
3350
3351 }
3352
3353 /* GroupOwner */
3354
3355 static void test_GroupOwner(void)
3356 {
3357
3358     LPDIRECTPLAY4 pDP[2];
3359     DPSESSIONDESC2 dpsd;
3360     DPID dpid[2], idGroup, idOwner;
3361     HRESULT hr;
3362     UINT i;
3363
3364
3365     for (i=0; i<2; i++)
3366     {
3367         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3368                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3369     }
3370     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
3371     dpsd.dwSize = sizeof(DPSESSIONDESC2);
3372     dpsd.guidApplication = appGuid;
3373     dpsd.dwMaxPlayers = 10;
3374     idGroup = 0;
3375     idOwner = 0;
3376
3377     /* Service provider not initialized */
3378     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3379     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
3380     check( 0, idOwner );
3381
3382     if ( hr == DP_OK )
3383     {
3384         todo_wine win_skip( "GetGroupOwner not implemented\n" );
3385         return;
3386     }
3387
3388
3389     for (i=0; i<2; i++)
3390         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
3391
3392     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
3393     checkHR( DP_OK, hr );
3394     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
3395                                     pDP[1], 0 );
3396     checkHR( DP_OK, hr );
3397
3398     for (i=0; i<2; i++)
3399     {
3400         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
3401                                         NULL, NULL, NULL, 0, 0 );
3402         checkHR( DP_OK, hr );
3403     }
3404
3405     /* Invalid group */
3406     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3407     checkHR( DPERR_INVALIDGROUP, hr );
3408
3409     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup, NULL, NULL, 0, 0 );
3410     checkHR( DP_OK, hr );
3411
3412     /* Fails, because we need a lobby session */
3413     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3414     checkHR( DPERR_UNSUPPORTED, hr );
3415
3416
3417     /* TODO:
3418      * - Make this work
3419      * - Check migration of the ownership of a group
3420      *   when the owner leaves
3421      */
3422
3423
3424     IDirectPlayX_Release( pDP[0] );
3425     IDirectPlayX_Release( pDP[1] );
3426
3427 }
3428
3429 /* EnumPlayers */
3430
3431 static BOOL CALLBACK EnumPlayers_cb( DPID dpId,
3432                                      DWORD dwPlayerType,
3433                                      LPCDPNAME lpName,
3434                                      DWORD dwFlags,
3435                                      LPVOID lpContext )
3436 {
3437     lpCallbackData callbackData = (lpCallbackData) lpContext;
3438     char playerIndex = dpid2char( callbackData->dpid,
3439                                   callbackData->dpidSize,
3440                                   dpId );
3441
3442
3443     /* Trace to study player ids */
3444     callbackData->szTrace1[ callbackData->dwCounter1 ] = playerIndex;
3445     callbackData->dwCounter1++;
3446     callbackData->szTrace1[ callbackData->dwCounter1 ] = '\0';
3447
3448     /* Trace to study flags received */
3449     strcat( callbackData->szTrace2,
3450             ( dwFlags2str(dwFlags, FLAGS_DPENUMPLAYERS) +
3451               strlen("DPENUMPLAYERS_") ) );
3452     strcat( callbackData->szTrace2, ":" );
3453
3454
3455     if ( playerIndex < '5' )
3456     {
3457         check( DPPLAYERTYPE_PLAYER, dwPlayerType );
3458     }
3459     else
3460     {
3461         check( DPPLAYERTYPE_GROUP, dwPlayerType );
3462     }
3463
3464     return TRUE;
3465
3466 }
3467
3468 static BOOL CALLBACK EnumSessions_cb_EnumPlayers( LPCDPSESSIONDESC2 lpThisSD,
3469                                                   LPDWORD lpdwTimeOut,
3470                                                   DWORD dwFlags,
3471                                                   LPVOID lpContext )
3472 {
3473     lpCallbackData callbackData = (lpCallbackData) lpContext;
3474     HRESULT hr;
3475
3476     if (dwFlags & DPESC_TIMEDOUT)
3477     {
3478         return FALSE;
3479     }
3480
3481     /* guid = NULL */
3482     callbackData->dwCounter1 = 0;
3483     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, NULL, EnumPlayers_cb,
3484                                    &callbackData, 0 );
3485     checkHR( DPERR_NOSESSIONS, hr );
3486     check( 0, callbackData->dwCounter1 );
3487
3488     /* guid = appGuid */
3489     callbackData->dwCounter1 = 0;
3490     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, (LPGUID) &appGuid,
3491                                    EnumPlayers_cb, &callbackData, 0 );
3492     checkHR( DPERR_NOSESSIONS, hr );
3493     check( 0, callbackData->dwCounter1 );
3494
3495     callbackData->dwCounter1 = 0;
3496     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, (LPGUID) &appGuid,
3497                                    EnumPlayers_cb, &callbackData,
3498                                    DPENUMPLAYERS_SESSION );
3499     checkHR( DPERR_NOSESSIONS, hr );
3500     check( 0, callbackData->dwCounter1 );
3501
3502     /* guid = guidInstance */
3503     callbackData->dwCounter1 = 0;
3504     hr = IDirectPlayX_EnumPlayers( callbackData->pDP,
3505                                    (LPGUID) &lpThisSD->guidInstance,
3506                                    EnumPlayers_cb, &callbackData, 0 );
3507     checkHR( DPERR_NOSESSIONS, hr );
3508     check( 0, callbackData->dwCounter1 );
3509
3510     callbackData->dwCounter1 = 0;
3511     hr = IDirectPlayX_EnumPlayers( callbackData->pDP,
3512                                    (LPGUID) &lpThisSD->guidInstance,
3513                                    EnumPlayers_cb, &callbackData,
3514                                    DPENUMPLAYERS_SESSION );
3515     checkHR( DPERR_GENERIC, hr ); /* Why? */
3516     check( 0, callbackData->dwCounter1 );
3517
3518     return TRUE;
3519
3520 }
3521
3522 static void test_EnumPlayers(void)
3523 {
3524     LPDIRECTPLAY4 pDP[3];
3525     DPSESSIONDESC2 dpsd[3];
3526     DPID dpid[5+2]; /* 5 players, 2 groups */
3527     CallbackData callbackData;
3528     HRESULT hr;
3529     UINT i;
3530
3531
3532     for (i=0; i<3; i++)
3533     {
3534         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3535                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3536
3537         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
3538         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
3539     }
3540
3541     dpsd[0].guidApplication = appGuid;
3542     dpsd[1].guidApplication = appGuid2;
3543     dpsd[2].guidApplication = GUID_NULL;
3544
3545     callbackData.dpid = dpid;
3546     callbackData.dpidSize = 5+2;
3547
3548
3549     /* Uninitialized service provider */
3550     callbackData.dwCounter1 = 0;
3551     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, NULL,
3552                                    &callbackData, 0 );
3553     checkHR( DPERR_UNINITIALIZED, hr );
3554     check( 0, callbackData.dwCounter1 );
3555
3556
3557     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
3558     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
3559     init_TCPIP_provider( pDP[2], "127.0.0.1", 0 );
3560
3561
3562     /* No session */
3563     callbackData.dwCounter1 = 0;
3564     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3565                                    &callbackData, 0 );
3566     todo_wine checkHR( DPERR_NOSESSIONS, hr );
3567     check( 0, callbackData.dwCounter1 );
3568
3569     if ( hr == DPERR_UNINITIALIZED )
3570     {
3571         todo_wine win_skip( "EnumPlayers not implemented\n" );
3572         return;
3573     }
3574
3575     callbackData.dwCounter1 = 0;
3576     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3577                                    &callbackData, 0 );
3578     checkHR( DPERR_NOSESSIONS, hr );
3579     check( 0, callbackData.dwCounter1 );
3580
3581     callbackData.dwCounter1 = 0;
3582     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3583                                    &callbackData, DPENUMPLAYERS_SESSION );
3584     checkHR( DPERR_NOSESSIONS, hr );
3585     check( 0, callbackData.dwCounter1 );
3586
3587
3588     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
3589     checkHR( DP_OK, hr );
3590     hr = IDirectPlayX_Open( pDP[1], &dpsd[1], DPOPEN_CREATE );
3591     checkHR( DP_OK, hr );
3592
3593
3594     /* No players */
3595     callbackData.dwCounter1 = 0;
3596     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3597                                    &callbackData, 0 );
3598     checkHR( DP_OK, hr );
3599     check( 0, callbackData.dwCounter1 );
3600
3601
3602     /* Create players */
3603     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
3604                                     NULL, NULL, NULL, 0,
3605                                     DPPLAYER_SERVERPLAYER );
3606     checkHR( DP_OK, hr );
3607     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
3608                                     NULL, NULL, NULL, 0,
3609                                     0 );
3610     checkHR( DP_OK, hr );
3611
3612     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[2],
3613                                     NULL, NULL, NULL, 0,
3614                                     0 );
3615     checkHR( DP_OK, hr );
3616     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[5],
3617                                    NULL, NULL, 0, 0 );
3618     checkHR( DP_OK, hr );
3619
3620
3621     /* Invalid parameters */
3622     callbackData.dwCounter1 = 0;
3623     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, NULL,
3624                                    &callbackData, 0 );
3625     checkHR( DPERR_INVALIDPARAMS, hr );
3626     check( 0, callbackData.dwCounter1 );
3627
3628     callbackData.dwCounter1 = 0;
3629     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3630                                    &callbackData, DPENUMPLAYERS_SESSION );
3631     checkHR( DPERR_INVALIDPARAMS, hr );
3632     check( 0, callbackData.dwCounter1 );
3633
3634
3635     /* Regular operation */
3636     callbackData.dwCounter1 = 0;
3637     callbackData.szTrace2[0] = 0;
3638     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3639                                    &callbackData, 0 );
3640     checkHR( DP_OK, hr );
3641     check( 2, callbackData.dwCounter1 );
3642     checkStr( "20", callbackData.szTrace1 );
3643     checkStr( "ALL:SERVERPLAYER:", callbackData.szTrace2 );
3644
3645     callbackData.dwCounter1 = 0;
3646     callbackData.szTrace2[0] = 0;
3647     hr = IDirectPlayX_EnumPlayers( pDP[1], NULL, EnumPlayers_cb,
3648                                    &callbackData, 0 );
3649     checkHR( DP_OK, hr );
3650     check( 1, callbackData.dwCounter1 );
3651     checkStr( "1", callbackData.szTrace1 );
3652     checkStr( "ALL:", callbackData.szTrace2 );
3653
3654     callbackData.dwCounter1 = 0;
3655     callbackData.szTrace2[0] = 0;
3656     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3657                                    &callbackData, 0 );
3658     checkHR( DP_OK, hr );
3659     check( 2, callbackData.dwCounter1 ); /* Guid is ignored */
3660     checkStr( "20", callbackData.szTrace1 );
3661     checkStr( "ALL:SERVERPLAYER:", callbackData.szTrace2 );
3662
3663
3664     /* Enumerating from a remote session */
3665     /* - Session not open */
3666     callbackData.pDP = pDP[2];
3667     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[2], 0,
3668                                     EnumSessions_cb_EnumPlayers,
3669                                     &callbackData, 0 );
3670     checkHR( DP_OK, hr );
3671
3672
3673     /* - Open session */
3674     callbackData.pDP = pDP[2];
3675     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[0], 0, EnumSessions_cb_join,
3676                                     pDP[2], 0 );
3677     checkHR( DP_OK, hr );
3678     hr = IDirectPlayX_CreatePlayer( pDP[2], &dpid[3],
3679                                     NULL, NULL, NULL, 0,
3680                                     DPPLAYER_SPECTATOR );
3681     checkHR( DP_OK, hr );
3682     hr = IDirectPlayX_CreatePlayer( pDP[2], &dpid[4],
3683                                     NULL, NULL, NULL, 0,
3684                                     0 );
3685     checkHR( DP_OK, hr );
3686     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[6],
3687                                    NULL, NULL, 0, 0 );
3688     checkHR( DP_OK, hr );
3689
3690     callbackData.dwCounter1 = 0;
3691     callbackData.szTrace2[0] = 0;
3692     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3693                                    &callbackData, 0 );
3694     checkHR( DP_OK, hr );
3695     check( 4, callbackData.dwCounter1 );
3696     checkStr( "4302", callbackData.szTrace1 );
3697     checkStr( "ALL:SPECTATOR:SERVERPLAYER:ALL:", callbackData.szTrace2 );
3698
3699
3700     /* Flag tests */
3701
3702     callbackData.dwCounter1 = 0;
3703     callbackData.szTrace2[0] = 0;
3704     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3705                                    &callbackData, DPENUMPLAYERS_ALL );
3706     checkHR( DP_OK, hr );
3707     check( 4, callbackData.dwCounter1 );
3708     checkStr( "4302", callbackData.szTrace1 );
3709     checkStr( "ALL:SPECTATOR:SERVERPLAYER:ALL:", callbackData.szTrace2 );
3710
3711     callbackData.dwCounter1 = 0;
3712     callbackData.szTrace2[0] = 0;
3713     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3714                                    &callbackData, DPENUMPLAYERS_GROUP );
3715     checkHR( DP_OK, hr );
3716     check( 6, callbackData.dwCounter1 );
3717     checkStr( "430256", callbackData.szTrace1 );
3718     checkStr( "GROUP:"
3719               "GROUP,DPENUMPLAYERS_SPECTATOR:"
3720               "GROUP,DPENUMPLAYERS_SERVERPLAYER:"
3721               "GROUP:ALL:ALL:", callbackData.szTrace2 );
3722
3723     callbackData.dwCounter1 = 0;
3724     callbackData.szTrace2[0] = 0;
3725     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3726                                    &callbackData, DPENUMPLAYERS_LOCAL );
3727     checkHR( DP_OK, hr );
3728     check( 2, callbackData.dwCounter1 );
3729     checkStr( "43", callbackData.szTrace1 );
3730     checkStr( "LOCAL:"
3731               "LOCAL,DPENUMPLAYERS_SPECTATOR:", callbackData.szTrace2 );
3732
3733     callbackData.dwCounter1 = 0;
3734     callbackData.szTrace2[0] = 0;
3735     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3736                                    &callbackData, DPENUMPLAYERS_SERVERPLAYER );
3737     checkHR( DP_OK, hr );
3738     check( 1, callbackData.dwCounter1 );
3739     checkStr( "0", callbackData.szTrace1 );
3740     checkStr( "SERVERPLAYER:", callbackData.szTrace2 );
3741
3742     callbackData.dwCounter1 = 0;
3743     callbackData.szTrace2[0] = 0;
3744     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3745                                    &callbackData, DPENUMPLAYERS_SPECTATOR );
3746     checkHR( DP_OK, hr );
3747     check( 1, callbackData.dwCounter1 );
3748     checkStr( "3", callbackData.szTrace1 );
3749     checkStr( "SPECTATOR:", callbackData.szTrace2 );
3750
3751
3752     IDirectPlayX_Release( pDP[0] );
3753     IDirectPlayX_Release( pDP[1] );
3754     IDirectPlayX_Release( pDP[2] );
3755
3756 }
3757
3758 /* EnumGroups */
3759
3760 static BOOL CALLBACK EnumGroups_cb( DPID dpId,
3761                                     DWORD dwPlayerType,
3762                                     LPCDPNAME lpName,
3763                                     DWORD dwFlags,
3764                                     LPVOID lpContext )
3765 {
3766     lpCallbackData callbackData = (lpCallbackData) lpContext;
3767     char playerIndex = dpid2char( callbackData->dpid,
3768                                   callbackData->dpidSize,
3769                                   dpId );
3770
3771
3772     /* Trace to study player ids */
3773     callbackData->szTrace1[ callbackData->dwCounter1 ] = playerIndex;
3774     callbackData->dwCounter1++;
3775     callbackData->szTrace1[ callbackData->dwCounter1 ] = '\0';
3776
3777     /* Trace to study flags received */
3778     strcat( callbackData->szTrace2,
3779             ( dwFlags2str(dwFlags, FLAGS_DPENUMGROUPS) +
3780               strlen("DPENUMGROUPS_") ) );
3781     strcat( callbackData->szTrace2, ":" );
3782
3783
3784     check( DPPLAYERTYPE_GROUP, dwPlayerType );
3785
3786     return TRUE;
3787 }
3788
3789 static BOOL CALLBACK EnumSessions_cb_EnumGroups( LPCDPSESSIONDESC2 lpThisSD,
3790                                                  LPDWORD lpdwTimeOut,
3791                                                  DWORD dwFlags,
3792                                                  LPVOID lpContext )
3793 {
3794     lpCallbackData callbackData = (lpCallbackData) lpContext;
3795     HRESULT hr;
3796
3797     if (dwFlags & DPESC_TIMEDOUT)
3798     {
3799         return FALSE;
3800     }
3801
3802     /* guid = NULL */
3803     callbackData->dwCounter1 = 0;
3804     hr = IDirectPlayX_EnumGroups( callbackData->pDP, NULL,
3805                                   EnumGroups_cb, &callbackData, 0 );
3806     checkHR( DPERR_NOSESSIONS, hr );
3807     check( 0, callbackData->dwCounter1 );
3808
3809     /* guid = appGuid */
3810     callbackData->dwCounter1 = 0;
3811     hr = IDirectPlayX_EnumGroups( callbackData->pDP, (LPGUID) &appGuid,
3812                                   EnumGroups_cb, &callbackData, 0 );
3813     checkHR( DPERR_NOSESSIONS, hr );
3814     check( 0, callbackData->dwCounter1 );
3815
3816     callbackData->dwCounter1 = 0;
3817     hr = IDirectPlayX_EnumGroups( callbackData->pDP, (LPGUID) &appGuid,
3818                                   EnumGroups_cb, &callbackData,
3819                                   DPENUMGROUPS_SESSION );
3820     checkHR( DPERR_NOSESSIONS, hr );
3821     check( 0, callbackData->dwCounter1 );
3822
3823     /* guid = guidInstance */
3824     callbackData->dwCounter1 = 0;
3825     hr = IDirectPlayX_EnumGroups( callbackData->pDP,
3826                                   (LPGUID) &lpThisSD->guidInstance,
3827                                   EnumGroups_cb, &callbackData, 0 );
3828     checkHR( DPERR_NOSESSIONS, hr );
3829     check( 0, callbackData->dwCounter1 );
3830
3831     callbackData->dwCounter1 = 0;
3832     hr = IDirectPlayX_EnumGroups( callbackData->pDP,
3833                                   (LPGUID) &lpThisSD->guidInstance,
3834                                   EnumGroups_cb, &callbackData,
3835                                   DPENUMGROUPS_SESSION );
3836     checkHR( DPERR_GENERIC, hr ); /* Why? */
3837     check( 0, callbackData->dwCounter1 );
3838
3839     return TRUE;
3840
3841 }
3842
3843 static void test_EnumGroups(void)
3844 {
3845     LPDIRECTPLAY4 pDP[3];
3846     DPSESSIONDESC2 dpsd[3];
3847     DPID dpid[5];
3848     CallbackData callbackData;
3849     HRESULT hr;
3850     UINT i;
3851
3852
3853     for (i=0; i<3; i++)
3854     {
3855         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3856                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3857
3858         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
3859         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
3860     }
3861
3862     dpsd[0].guidApplication = appGuid;
3863     dpsd[1].guidApplication = appGuid2;
3864     dpsd[2].guidApplication = GUID_NULL;
3865
3866     callbackData.dpid = dpid;
3867     callbackData.dpidSize = 5;
3868
3869
3870     /* Uninitialized service provider */
3871     callbackData.dwCounter1 = 0;
3872     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3873                                   &callbackData, 0 );
3874     checkHR( DPERR_UNINITIALIZED, hr );
3875     check( 0, callbackData.dwCounter1 );
3876
3877
3878     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
3879     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
3880     init_TCPIP_provider( pDP[2], "127.0.0.1", 0 );
3881
3882
3883     /* No session */
3884     callbackData.dwCounter1 = 0;
3885     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3886                                   &callbackData, 0 );
3887     todo_wine checkHR( DPERR_NOSESSIONS, hr );
3888     check( 0, callbackData.dwCounter1 );
3889
3890     if ( hr == DPERR_UNINITIALIZED )
3891     {
3892         todo_wine win_skip( "EnumGroups not implemented\n" );
3893         return;
3894     }
3895
3896     callbackData.dwCounter1 = 0;
3897     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, EnumGroups_cb,
3898                                   &callbackData, 0 );
3899     checkHR( DPERR_NOSESSIONS, hr );
3900     check( 0, callbackData.dwCounter1 );
3901
3902     callbackData.dwCounter1 = 0;
3903     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, EnumGroups_cb,
3904                                   &callbackData, DPENUMGROUPS_SESSION );
3905     checkHR( DPERR_NOSESSIONS, hr );
3906     check( 0, callbackData.dwCounter1 );
3907
3908
3909     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
3910     checkHR( DP_OK, hr );
3911     hr = IDirectPlayX_Open( pDP[1], &dpsd[1], DPOPEN_CREATE );
3912     checkHR( DP_OK, hr );
3913
3914
3915     /* No groups */
3916     callbackData.dwCounter1 = 0;
3917     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3918                                   &callbackData, 0 );
3919     checkHR( DP_OK, hr );
3920     check( 0, callbackData.dwCounter1 );
3921
3922
3923     /* Create groups */
3924     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[0],
3925                                    NULL, NULL, 0, 0 );
3926     checkHR( DP_OK, hr );
3927     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[0], &dpid[3],
3928                                           NULL, NULL, 0, 0 );
3929     checkHR( DP_OK, hr ); /* Not a superior level group,
3930                              won't appear in the enumerations */
3931     hr = IDirectPlayX_CreateGroup( pDP[1], &dpid[1],
3932                                    NULL, NULL, 0, 0 );
3933     checkHR( DP_OK, hr );
3934     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[2],
3935                                    NULL, NULL, 0, DPGROUP_HIDDEN );
3936     checkHR( DP_OK, hr );
3937
3938
3939     /* Invalid parameters */
3940     callbackData.dwCounter1 = 0;
3941     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, NULL,
3942                                   &callbackData, 0 );
3943     checkHR( DPERR_INVALIDPARAMS, hr );
3944     check( 0, callbackData.dwCounter1 );
3945
3946     callbackData.dwCounter1 = 0;
3947     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3948                                   &callbackData, DPENUMGROUPS_SESSION );
3949     checkHR( DPERR_INVALIDPARAMS, hr );
3950     check( 0, callbackData.dwCounter1 );
3951
3952
3953     /* Regular operation */
3954     callbackData.dwCounter1 = 0;
3955     callbackData.szTrace2[0] = 0;
3956     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3957                                   &callbackData, 0 );
3958     checkHR( DP_OK, hr );
3959     check( 2, callbackData.dwCounter1 );
3960     checkStr( "02", callbackData.szTrace1 );
3961     checkStr( "ALL:HIDDEN:", callbackData.szTrace2 );
3962
3963     callbackData.dwCounter1 = 0;
3964     callbackData.szTrace2[0] = 0;
3965     hr = IDirectPlayX_EnumGroups( pDP[1], NULL, EnumGroups_cb,
3966                                   &callbackData, 0 );
3967     checkHR( DP_OK, hr );
3968     check( 1, callbackData.dwCounter1 );
3969     checkStr( "1", callbackData.szTrace1 );
3970     checkStr( "ALL:", callbackData.szTrace2 );
3971
3972     callbackData.dwCounter1 = 0;
3973     callbackData.szTrace2[0] = 0;
3974     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, EnumGroups_cb,
3975                                   &callbackData, 0 );
3976     checkHR( DP_OK, hr );
3977     check( 2, callbackData.dwCounter1 ); /* Guid is ignored */
3978     checkStr( "02", callbackData.szTrace1 );
3979     checkStr( "ALL:HIDDEN:", callbackData.szTrace2 );
3980
3981
3982     /* Enumerating from a remote session */
3983     /* - Session not open */
3984     callbackData.pDP = pDP[2];
3985     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[2], 0,
3986                                     EnumSessions_cb_EnumGroups,
3987                                     &callbackData, 0 );
3988     checkHR( DP_OK, hr );
3989
3990     /* - Open session */
3991     callbackData.pDP = pDP[2];
3992     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[0], 0, EnumSessions_cb_join,
3993                                     pDP[2], 0 );
3994     checkHR( DP_OK, hr );
3995
3996     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[3],
3997                                    NULL, NULL, 0, 0 );
3998     checkHR( DP_OK, hr );
3999     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[4],
4000                                    NULL, NULL, 0, DPGROUP_STAGINGAREA );
4001     checkHR( DP_OK, hr );
4002
4003
4004     callbackData.dwCounter1 = 0;
4005     callbackData.szTrace2[0] = 0;
4006     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4007                                   &callbackData, 0 );
4008     checkHR( DP_OK, hr );
4009     check( 4, callbackData.dwCounter1 );
4010     checkStr( "0234", callbackData.szTrace1 );
4011     checkStr( "ALL:HIDDEN:ALL:STAGINGAREA:", callbackData.szTrace2 );
4012
4013     /* Flag tests */
4014     callbackData.dwCounter1 = 0;
4015     callbackData.szTrace2[0] = 0;
4016     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4017                                   &callbackData, DPENUMGROUPS_ALL );
4018     checkHR( DP_OK, hr );
4019     check( 4, callbackData.dwCounter1 );
4020     checkStr( "0234", callbackData.szTrace1 );
4021     checkStr( "ALL:HIDDEN:ALL:STAGINGAREA:", callbackData.szTrace2 );
4022
4023     callbackData.dwCounter1 = 0;
4024     callbackData.szTrace2[0] = 0;
4025     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4026                                   &callbackData, DPENUMGROUPS_HIDDEN );
4027     checkHR( DP_OK, hr );
4028     check( 1, callbackData.dwCounter1 );
4029     checkStr( "2", callbackData.szTrace1 );
4030     checkStr( "HIDDEN:", callbackData.szTrace2 );
4031
4032     callbackData.dwCounter1 = 0;
4033     callbackData.szTrace2[0] = 0;
4034     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4035                                   &callbackData, DPENUMGROUPS_LOCAL );
4036     checkHR( DP_OK, hr );
4037     check( 2, callbackData.dwCounter1 );
4038     checkStr( "34", callbackData.szTrace1 );
4039     checkStr( "LOCAL:"
4040               "LOCAL,DPENUMGROUPS_STAGINGAREA:", callbackData.szTrace2 );
4041
4042     callbackData.dwCounter1 = 0;
4043     callbackData.szTrace2[0] = 0;
4044     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4045                                   &callbackData, DPENUMGROUPS_REMOTE );
4046     checkHR( DP_OK, hr );
4047     check( 2, callbackData.dwCounter1 );
4048     checkStr( "02", callbackData.szTrace1 );
4049     checkStr( "REMOTE:"
4050               "REMOTE,DPENUMGROUPS_HIDDEN:", callbackData.szTrace2 );
4051
4052     callbackData.dwCounter1 = 0;
4053     callbackData.szTrace2[0] = 0;
4054     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4055                                   &callbackData, DPENUMGROUPS_STAGINGAREA );
4056     checkHR( DP_OK, hr );
4057     check( 1, callbackData.dwCounter1 );
4058     checkStr( "4", callbackData.szTrace1 );
4059     checkStr( "STAGINGAREA:", callbackData.szTrace2 );
4060
4061
4062     IDirectPlayX_Release( pDP[0] );
4063     IDirectPlayX_Release( pDP[1] );
4064     IDirectPlayX_Release( pDP[2] );
4065
4066 }
4067
4068 static void test_EnumGroupsInGroup(void)
4069 {
4070     LPDIRECTPLAY4 pDP[2];
4071     DPSESSIONDESC2 dpsd[2];
4072     DPID dpid[6];
4073     CallbackData callbackData;
4074     HRESULT hr;
4075     UINT i;
4076
4077
4078     for (i=0; i<2; i++)
4079     {
4080         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4081                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4082
4083         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
4084         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
4085     }
4086
4087     dpsd[0].guidApplication = appGuid;
4088     dpsd[1].guidApplication = GUID_NULL;
4089
4090     callbackData.dpid = dpid;
4091     callbackData.dpidSize = 6;
4092
4093
4094     /* Uninitialized service provider */
4095     callbackData.dwCounter1 = 0;
4096     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], 0, NULL, EnumGroups_cb,
4097                                          &callbackData, 0 );
4098     checkHR( DPERR_UNINITIALIZED, hr );
4099     check( 0, callbackData.dwCounter1 );
4100
4101
4102     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4103     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4104
4105     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
4106     todo_wine checkHR( DP_OK, hr );
4107
4108     if ( hr == DPERR_UNINITIALIZED )
4109     {
4110         todo_wine win_skip( "EnumGroupsInGroup not implemented\n" );
4111         return;
4112     }
4113
4114     /* Create groups */
4115     /*
4116      * 0
4117      *   / 2
4118      * 1 | 3
4119      *   | 4
4120      *   \ 5 (shortcut)
4121      */
4122     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[0],
4123                                    NULL, NULL, 0, 0 );
4124     checkHR( DP_OK, hr );
4125     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[1],
4126                                    NULL, NULL, 0, 0 );
4127     checkHR( DP_OK, hr );
4128     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[1], &dpid[2],
4129                                           NULL, NULL, 0, 0 );
4130     checkHR( DP_OK, hr );
4131     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[1], &dpid[3],
4132                                           NULL, NULL, 0,
4133                                           DPGROUP_HIDDEN );
4134     checkHR( DP_OK, hr );
4135     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[1], &dpid[4],
4136                                           NULL, NULL, 0,
4137                                           DPGROUP_STAGINGAREA );
4138     checkHR( DP_OK, hr );
4139     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[5],
4140                                    NULL, NULL, 0, 0 );
4141     checkHR( DP_OK, hr );
4142
4143     hr = IDirectPlayX_AddGroupToGroup( pDP[0], dpid[1], dpid[5] );
4144     checkHR( DP_OK, hr );
4145
4146
4147     /* Invalid parameters */
4148     callbackData.dwCounter1 = 0;
4149     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], 0, NULL, EnumGroups_cb,
4150                                          &callbackData, 0 );
4151     checkHR( DPERR_INVALIDGROUP, hr );
4152     check( 0, callbackData.dwCounter1 );
4153
4154     callbackData.dwCounter1 = 0;
4155     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], 10, NULL, EnumGroups_cb,
4156                                          &callbackData, 0 );
4157     checkHR( DPERR_INVALIDGROUP, hr );
4158     check( 0, callbackData.dwCounter1 );
4159
4160     callbackData.dwCounter1 = 0;
4161     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], (LPGUID) &appGuid,
4162                                          NULL, &callbackData, 0 );
4163     checkHR( DPERR_INVALIDPARAMS, hr );
4164     check( 0, callbackData.dwCounter1 );
4165
4166     callbackData.dwCounter1 = 0;
4167     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4168                                          &callbackData, DPENUMGROUPS_SESSION );
4169     checkHR( DPERR_INVALIDPARAMS, hr );
4170     check( 0, callbackData.dwCounter1 );
4171
4172
4173     /* Regular operation */
4174     callbackData.dwCounter1 = 0;
4175     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[0], NULL, EnumGroups_cb,
4176                                          &callbackData, 0 );
4177     checkHR( DP_OK, hr );
4178     check( 0, callbackData.dwCounter1 );
4179
4180     callbackData.dwCounter1 = 0;
4181     callbackData.szTrace2[0] = 0;
4182     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4183                                          &callbackData, 0 );
4184     checkHR( DP_OK, hr );
4185     check( 4, callbackData.dwCounter1 );
4186     checkStr( "5432", callbackData.szTrace1 );
4187     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4188
4189     callbackData.dwCounter1 = 0;
4190     callbackData.szTrace2[0] = 0;
4191     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], (LPGUID) &appGuid,
4192                                          EnumGroups_cb, &callbackData, 0 );
4193     checkHR( DP_OK, hr );
4194     check( 4, callbackData.dwCounter1 ); /* Guid is ignored */
4195     checkStr( "5432", callbackData.szTrace1 );
4196     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4197
4198
4199     /* Enumerating from a remote session */
4200     /* - Session not open */
4201     callbackData.pDP = pDP[1];
4202     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd[1], 0,
4203                                     EnumSessions_cb_EnumGroups,
4204                                     &callbackData, 0 );
4205     checkHR( DP_OK, hr );
4206
4207     /* - Open session */
4208     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd[0], 0, EnumSessions_cb_join,
4209                                     pDP[1], 0 );
4210     checkHR( DP_OK, hr );
4211
4212
4213     callbackData.dwCounter1 = 0;
4214     callbackData.szTrace2[0] = 0;
4215     hr = IDirectPlayX_EnumGroupsInGroup( pDP[1], dpid[1], NULL, EnumGroups_cb,
4216                                          &callbackData, 0 );
4217     checkHR( DP_OK, hr );
4218     check( 4, callbackData.dwCounter1 );
4219     checkStr( "5432", callbackData.szTrace1 );
4220     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4221
4222     /* Flag tests */
4223     callbackData.dwCounter1 = 0;
4224     callbackData.szTrace2[0] = 0;
4225     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4226                                          &callbackData, DPENUMGROUPS_ALL );
4227     checkHR( DP_OK, hr );
4228     check( 4, callbackData.dwCounter1 );
4229     checkStr( "5432", callbackData.szTrace1 );
4230     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4231
4232     callbackData.dwCounter1 = 0;
4233     callbackData.szTrace2[0] = 0;
4234     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4235                                          &callbackData, DPENUMGROUPS_HIDDEN );
4236     checkHR( DP_OK, hr );
4237     check( 1, callbackData.dwCounter1 );
4238     checkStr( "3", callbackData.szTrace1 );
4239     checkStr( "HIDDEN:", callbackData.szTrace2 );
4240
4241     callbackData.dwCounter1 = 0;
4242     callbackData.szTrace2[0] = 0;
4243     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4244                                          &callbackData, DPENUMGROUPS_LOCAL );
4245     checkHR( DP_OK, hr );
4246     check( 4, callbackData.dwCounter1 );
4247     checkStr( "5432", callbackData.szTrace1 );
4248     checkStr( "LOCAL,DPENUMGROUPS_SHORTCUT:"
4249               "LOCAL,DPENUMGROUPS_STAGINGAREA:"
4250               "LOCAL,DPENUMGROUPS_HIDDEN:LOCAL:", callbackData.szTrace2 );
4251
4252     callbackData.dwCounter1 = 0;
4253     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4254                                          &callbackData, DPENUMGROUPS_REMOTE );
4255     checkHR( DP_OK, hr );
4256     check( 0, callbackData.dwCounter1 );
4257
4258     callbackData.dwCounter1 = 0;
4259     hr = IDirectPlayX_EnumGroupsInGroup( pDP[1], dpid[1], NULL, EnumGroups_cb,
4260                                          &callbackData, DPENUMGROUPS_LOCAL );
4261     checkHR( DP_OK, hr );
4262     check( 0, callbackData.dwCounter1 );
4263
4264     callbackData.dwCounter1 = 0;
4265     callbackData.szTrace2[0] = 0;
4266     hr = IDirectPlayX_EnumGroupsInGroup( pDP[1], dpid[1], NULL, EnumGroups_cb,
4267                                          &callbackData, DPENUMGROUPS_REMOTE );
4268     checkHR( DP_OK, hr );
4269     check( 4, callbackData.dwCounter1 );
4270     checkStr( "5432", callbackData.szTrace1 );
4271     checkStr( "REMOTE,DPENUMGROUPS_SHORTCUT:"
4272               "REMOTE,DPENUMGROUPS_STAGINGAREA:"
4273               "REMOTE,DPENUMGROUPS_HIDDEN:REMOTE:", callbackData.szTrace2 );
4274
4275     callbackData.dwCounter1 = 0;
4276     callbackData.szTrace2[0] = 0;
4277     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4278                                          &callbackData, DPENUMGROUPS_SHORTCUT );
4279     checkHR( DP_OK, hr );
4280     check( 1, callbackData.dwCounter1 );
4281     checkStr( "5", callbackData.szTrace1 );
4282     checkStr( "SHORTCUT:", callbackData.szTrace2 );
4283
4284     callbackData.dwCounter1 = 0;
4285     callbackData.szTrace2[0] = 0;
4286     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4287                                          &callbackData,
4288                                          DPENUMGROUPS_STAGINGAREA );
4289     checkHR( DP_OK, hr );
4290     check( 1, callbackData.dwCounter1 );
4291     checkStr( "4", callbackData.szTrace1 );
4292     checkStr( "STAGINGAREA:", callbackData.szTrace2 );
4293
4294
4295     IDirectPlayX_Release( pDP[0] );
4296     IDirectPlayX_Release( pDP[1] );
4297
4298 }
4299
4300 static void test_groups_p2p(void)
4301 {
4302
4303     LPDIRECTPLAY4 pDP[2];
4304     DPSESSIONDESC2 dpsd;
4305     DPID idPlayer[6], idGroup[3];
4306     HRESULT hr;
4307     UINT i;
4308
4309     DWORD dwDataSize = 1024;
4310     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
4311     CallbackData callbackData;
4312
4313
4314     for (i=0; i<2; i++)
4315     {
4316         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4317                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4318     }
4319     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
4320     dpsd.dwSize = sizeof(DPSESSIONDESC2);
4321     dpsd.guidApplication = appGuid;
4322     dpsd.dwMaxPlayers = 10;
4323
4324
4325     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4326     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4327
4328     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4329     todo_wine checkHR( DP_OK, hr );
4330     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
4331                                     pDP[1], 0 );
4332     todo_wine checkHR( DP_OK, hr );
4333
4334     if ( hr == DPERR_UNINITIALIZED )
4335     {
4336         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
4337         return;
4338     }
4339
4340
4341     /* Create players */
4342     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[0],
4343                                     NULL, NULL, NULL, 0, 0 );
4344     checkHR( DP_OK, hr );
4345     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[1],
4346                                     NULL, NULL, NULL, 0, 0 );
4347     checkHR( DP_OK, hr );
4348     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[2],
4349                                     NULL, NULL, NULL, 0, 0 );
4350     checkHR( DP_OK, hr );
4351     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[3],
4352                                     NULL, NULL, NULL, 0, 0 );
4353     checkHR( DP_OK, hr );
4354     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[4],
4355                                     NULL, NULL, NULL, 0, 0 );
4356     checkHR( DP_OK, hr );
4357     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[5],
4358                                     NULL, NULL, NULL, 0, 0 );
4359     checkHR( DP_OK, hr );
4360
4361     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup[0],
4362                                    NULL, NULL, 0, 0 );
4363     checkHR( DP_OK, hr );
4364     hr = IDirectPlayX_CreateGroup( pDP[1], &idGroup[2],
4365                                    NULL, NULL, 0, 0 );
4366     checkHR( DP_OK, hr );
4367     hr = IDirectPlayX_CreateGroupInGroup( pDP[1], idGroup[2], &idGroup[1],
4368                                           NULL, NULL, 0, 0 );
4369     checkHR( DP_OK, hr );
4370
4371
4372     /* Purge queues */
4373     check_messages( pDP[0], idPlayer, 6, &callbackData );
4374     checkStr( "S0," "S1,S0,"
4375               "S2,S1,S0," "S2,S1,S0,"
4376               "S2,S1,S0," "S2,S1,S0,"
4377               "S2,S1,S0," "S2,S1,S0,", callbackData.szTrace1 );
4378     check_messages( pDP[1], idPlayer, 6, &callbackData );
4379     checkStr( "S3," "S4,S3,"
4380               "S5,S4,S3," "S5,S4,S3,"
4381               "S5,S4,S3,", callbackData.szTrace1 );
4382
4383
4384     /*
4385      * Player 0   |                  |
4386      * Player 1   | Group 0          | pDP 0
4387      * Player 2   |                  |
4388      * Player 3  | Group 1 )          |
4389      * Player 4  |         | Group 2  | pDP 1
4390      * Player 5            |          |
4391      */
4392
4393     /* Build groups */
4394     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[0] );
4395     checkHR( DP_OK, hr );
4396     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[1] );
4397     checkHR( DP_OK, hr );
4398     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[2] );
4399     checkHR( DP_OK, hr );
4400     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[3] );
4401     checkHR( DP_OK, hr );
4402     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[4] );
4403     checkHR( DP_OK, hr );
4404     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[4] );
4405     checkHR( DP_OK, hr );
4406     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[5] );
4407     checkHR( DP_OK, hr );
4408
4409     hr = IDirectPlayX_AddGroupToGroup( pDP[1], idGroup[2], idGroup[1] );
4410     checkHR( DP_OK, hr );
4411
4412     /* Purge queues */
4413     check_messages( pDP[0], idPlayer, 6, &callbackData );
4414     checkStr( "S2,S1,S0," "S2,S1,S0," "S2,S1,S0,"
4415               "S2,S1,S0," "S2,S1,S0," "S2,S1,S0,"
4416               "S2,S1,S0,", callbackData.szTrace1 );
4417     check_messages( pDP[1], idPlayer, 6, &callbackData );
4418     checkStr( "S5,S4,S3," "S5,S4,S3," "S5,S4,S3,"
4419               "S5,S4,S3," "S5,S4,S3," "S5,S4,S3,"
4420               "S5,S4,S3,", callbackData.szTrace1 );
4421
4422
4423     /* Sending broadcast messages, and checking who receives them */
4424
4425     dwDataSize = 4;
4426     /* 0 -> * */
4427     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], DPID_ALLPLAYERS, 0,
4428                             lpData, dwDataSize );
4429     checkHR( DP_OK, hr );
4430     check_messages( pDP[0], idPlayer, 6, &callbackData );
4431     checkStr( "02,01,", callbackData.szTrace1 );
4432     check_messages( pDP[1], idPlayer, 6, &callbackData );
4433     checkStr( "05,04,03,", callbackData.szTrace1 );
4434
4435     /* 0 -> g0 */
4436     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[0], 0,
4437                             lpData, dwDataSize );
4438     checkHR( DP_OK, hr );
4439     check_messages( pDP[0], idPlayer, 6, &callbackData );
4440     checkStr( "02,01,", callbackData.szTrace1 );
4441     check_messages( pDP[1], idPlayer, 6, &callbackData );
4442     checkStr( "", callbackData.szTrace1 );
4443     /* 0 -> g1 */
4444     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[1], 0,
4445                             lpData, dwDataSize );
4446     checkHR( DP_OK, hr );
4447     check_messages( pDP[0], idPlayer, 6, &callbackData );
4448     checkStr( "", callbackData.szTrace1 );
4449     check_messages( pDP[1], idPlayer, 6, &callbackData );
4450     checkStr( "04,03,", callbackData.szTrace1 );
4451     /* 0 -> g2 */
4452     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[2], 0,
4453                             lpData, dwDataSize );
4454     checkHR( DP_OK, hr );
4455     check_messages( pDP[0], idPlayer, 6, &callbackData );
4456     checkStr( "", callbackData.szTrace1 );
4457     check_messages( pDP[1], idPlayer, 6, &callbackData );
4458     checkStr( "05,04,", callbackData.szTrace1 );
4459
4460     /* 3 -> * */
4461     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], DPID_ALLPLAYERS, 0,
4462                             lpData, dwDataSize );
4463     checkHR( DP_OK, hr );
4464     check_messages( pDP[0], idPlayer, 6, &callbackData );
4465     checkStr( "32,31,30,", callbackData.szTrace1 );
4466     check_messages( pDP[1], idPlayer, 6, &callbackData );
4467     checkStr( "35,34,", callbackData.szTrace1 );
4468     /* 3 -> g0 */
4469     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[0], 0,
4470                             lpData, dwDataSize );
4471     checkHR( DP_OK, hr );
4472     check_messages( pDP[0], idPlayer, 6, &callbackData );
4473     checkStr( "32,31,30,", callbackData.szTrace1 );
4474     check_messages( pDP[1], idPlayer, 6, &callbackData );
4475     checkStr( "", callbackData.szTrace1 );
4476     /* 3 -> g1 */
4477     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[1], 0,
4478                             lpData, dwDataSize );
4479     checkHR( DP_OK, hr );
4480     check_messages( pDP[0], idPlayer, 6, &callbackData );
4481     checkStr( "", callbackData.szTrace1 );
4482     check_messages( pDP[1], idPlayer, 6, &callbackData );
4483     checkStr( "34,", callbackData.szTrace1 );
4484     /* 3 -> g2 */
4485     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[2], 0,
4486                             lpData, dwDataSize );
4487     checkHR( DP_OK, hr );
4488     check_messages( pDP[0], idPlayer, 6, &callbackData );
4489     checkStr( "", callbackData.szTrace1 );
4490     check_messages( pDP[1], idPlayer, 6, &callbackData );
4491     checkStr( "35,34,", callbackData.szTrace1 );
4492
4493     /* 5 -> * */
4494     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], DPID_ALLPLAYERS, 0,
4495                             lpData, dwDataSize );
4496     checkHR( DP_OK, hr );
4497     check_messages( pDP[0], idPlayer, 6, &callbackData );
4498     checkStr( "52,51,50,", callbackData.szTrace1 );
4499     check_messages( pDP[1], idPlayer, 6, &callbackData );
4500     checkStr( "54,53,", callbackData.szTrace1 );
4501     /* 5 -> g0 */
4502     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[0], 0,
4503                             lpData, dwDataSize );
4504     checkHR( DP_OK, hr );
4505     check_messages( pDP[0], idPlayer, 6, &callbackData );
4506     checkStr( "52,51,50,", callbackData.szTrace1 );
4507     check_messages( pDP[1], idPlayer, 6, &callbackData );
4508     checkStr( "", callbackData.szTrace1 );
4509     /* 5 -> g1 */
4510     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[1], 0,
4511                             lpData, dwDataSize );
4512     checkHR( DP_OK, hr );
4513     check_messages( pDP[0], idPlayer, 6, &callbackData );
4514     checkStr( "", callbackData.szTrace1 );
4515     check_messages( pDP[1], idPlayer, 6, &callbackData );
4516     checkStr( "54,53,", callbackData.szTrace1 );
4517     /* 5 -> g2 */
4518     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[2], 0,
4519                             lpData, dwDataSize );
4520     checkHR( DP_OK, hr );
4521     check_messages( pDP[0], idPlayer, 6, &callbackData );
4522     checkStr( "", callbackData.szTrace1 );
4523     check_messages( pDP[1], idPlayer, 6, &callbackData );
4524     checkStr( "54,", callbackData.szTrace1 );
4525
4526
4527     HeapFree( GetProcessHeap(), 0, lpData );
4528     IDirectPlayX_Release( pDP[0] );
4529     IDirectPlayX_Release( pDP[1] );
4530
4531 }
4532
4533 static void test_groups_cs(void)
4534 {
4535
4536     LPDIRECTPLAY4 pDP[2];
4537     DPSESSIONDESC2 dpsd;
4538     DPID idPlayer[6], idGroup[3];
4539     CallbackData callbackData;
4540     HRESULT hr;
4541     UINT i;
4542
4543     DWORD dwDataSize = 1024;
4544     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
4545
4546
4547     for (i=0; i<2; i++)
4548     {
4549         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4550                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4551     }
4552     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
4553     dpsd.dwSize = sizeof(DPSESSIONDESC2);
4554     dpsd.guidApplication = appGuid;
4555     dpsd.dwMaxPlayers = 10;
4556
4557
4558     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4559     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4560
4561     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
4562     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4563     todo_wine checkHR( DP_OK, hr );
4564     dpsd.dwFlags = 0;
4565     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
4566                                     pDP[1], 0 );
4567     todo_wine checkHR( DP_OK, hr );
4568
4569     if ( hr == DPERR_UNINITIALIZED )
4570     {
4571         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
4572         return;
4573     }
4574
4575
4576     /* Create players */
4577     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[0],
4578                                     NULL, NULL, NULL, 0, 0 );
4579     checkHR( DPERR_ACCESSDENIED, hr );
4580     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[0],
4581                                     NULL, NULL, NULL, 0,
4582                                     DPPLAYER_SERVERPLAYER );
4583     checkHR( DP_OK, hr );
4584     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[1],
4585                                     NULL, NULL, NULL, 0, 0 );
4586     checkHR( DPERR_ACCESSDENIED, hr );
4587     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[1],
4588                                     NULL, NULL, NULL, 0, 0 );
4589     checkHR( DP_OK, hr );
4590     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[2],
4591                                     NULL, NULL, NULL, 0, 0 );
4592     checkHR( DP_OK, hr );
4593     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[3],
4594                                     NULL, NULL, NULL, 0, 0 );
4595     checkHR( DP_OK, hr );
4596     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[4],
4597                                     NULL, NULL, NULL, 0, 0 );
4598     checkHR( DP_OK, hr );
4599     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[5],
4600                                     NULL, NULL, NULL, 0, 0 );
4601     checkHR( DP_OK, hr );
4602
4603     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup[0],
4604                                    NULL, NULL, 0, 0 );
4605     checkHR( DP_OK, hr );
4606     hr = IDirectPlayX_CreateGroup( pDP[1], &idGroup[2],
4607                                    NULL, NULL, 0, 0 );
4608     checkHR( DP_OK, hr );
4609     hr = IDirectPlayX_CreateGroupInGroup( pDP[1], idGroup[2], &idGroup[1],
4610                                           NULL, NULL, 0, 0 );
4611     checkHR( DP_OK, hr );
4612
4613
4614     /* Purge queues */
4615     check_messages( pDP[0], idPlayer, 6, &callbackData );
4616     checkStr( "S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
4617     check_messages( pDP[1], idPlayer, 6, &callbackData );
4618     checkStr( "S1," "S2,S1," "S3,S2,S1," "S4,S3,S2,S1,"
4619               "S5,S4,S3,S2,S1," "S5,S4,S3,S2,S1,", callbackData.szTrace1 );
4620
4621     /*
4622      * Player 0   |                  | pDP 0
4623      * Player 1   | Group 0           |
4624      * Player 2   |                   |
4625      * Player 3  | Group 1 )          |
4626      * Player 4  |         | Group 2  | pDP 1
4627      * Player 5            |          |
4628      */
4629
4630     /* Build groups */
4631     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[0] );
4632     checkHR( DP_OK, hr );
4633     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[1] );
4634     checkHR( DP_OK, hr );
4635     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[2] );
4636     checkHR( DP_OK, hr );
4637     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[3] );
4638     checkHR( DP_OK, hr );
4639     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[4] );
4640     checkHR( DP_OK, hr );
4641     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[4] );
4642     checkHR( DP_OK, hr );
4643     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[5] );
4644     checkHR( DP_OK, hr );
4645
4646     hr = IDirectPlayX_AddGroupToGroup( pDP[1], idGroup[2], idGroup[1] );
4647     checkHR( DP_OK, hr );
4648
4649     /* Purge queues */
4650     check_messages( pDP[0], idPlayer, 6, &callbackData );
4651     checkStr( "S0,S0,S0,S0,", callbackData.szTrace1 );
4652     check_messages( pDP[1], idPlayer, 6, &callbackData );
4653     checkStr( "S5," "S4,S3,S2,S1," "S5,S4,S3,S2,S1,"
4654               "S5,S4,S3,S2,S1," "S5,S4,S3,S2,S1,", callbackData.szTrace1 );
4655
4656
4657     /* Sending broadcast messages, and checking who receives them */
4658     dwDataSize = 4;
4659     /* 0 -> * */
4660     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], DPID_ALLPLAYERS, 0,
4661                             lpData, dwDataSize );
4662     checkHR( DP_OK, hr );
4663     check_messages( pDP[0], idPlayer, 6, &callbackData );
4664     checkStr( "", callbackData.szTrace1 );
4665     check_messages( pDP[1], idPlayer, 6, &callbackData );
4666     checkStr( "05,04,03,02,01,", callbackData.szTrace1 );
4667
4668     /* 0 -> g0 */
4669     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[0], 0,
4670                             lpData, dwDataSize );
4671     checkHR( DP_OK, hr );
4672     check_messages( pDP[0], idPlayer, 6, &callbackData );
4673     checkStr( "", callbackData.szTrace1 );
4674     check_messages( pDP[1], idPlayer, 6, &callbackData );
4675     checkStr( "02,01,", callbackData.szTrace1 );
4676     /* 0 -> g1 */
4677     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[1], 0,
4678                             lpData, dwDataSize );
4679     checkHR( DPERR_INVALIDPARAMS, hr );
4680     check_messages( pDP[0], idPlayer, 6, &callbackData );
4681     checkStr( "", callbackData.szTrace1 );
4682     check_messages( pDP[1], idPlayer, 6, &callbackData );
4683     checkStr( "", callbackData.szTrace1 );
4684     /* 0 -> g2 */
4685     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[2], 0,
4686                             lpData, dwDataSize );
4687     checkHR( DPERR_INVALIDPARAMS, hr );
4688     check_messages( pDP[0], idPlayer, 6, &callbackData );
4689     checkStr( "", callbackData.szTrace1 );
4690     check_messages( pDP[1], idPlayer, 6, &callbackData );
4691     checkStr( "", callbackData.szTrace1 );
4692
4693     /* 3 -> * */
4694     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], DPID_ALLPLAYERS, 0,
4695                             lpData, dwDataSize );
4696     checkHR( DP_OK, hr );
4697     check_messages( pDP[0], idPlayer, 6, &callbackData );
4698     checkStr( "30,", callbackData.szTrace1 );
4699     check_messages( pDP[1], idPlayer, 6, &callbackData );
4700     checkStr( "35,34,32,31,", callbackData.szTrace1 );
4701     /* 3 -> g0 */
4702     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[0], 0,
4703                             lpData, dwDataSize );
4704     checkHR( DPERR_INVALIDPARAMS, hr );
4705     check_messages( pDP[0], idPlayer, 6, &callbackData );
4706     checkStr( "", callbackData.szTrace1 );
4707     check_messages( pDP[1], idPlayer, 6, &callbackData );
4708     checkStr( "", callbackData.szTrace1 );
4709     /* 3 -> g1 */
4710     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[1], 0,
4711                             lpData, dwDataSize );
4712     checkHR( DP_OK, hr );
4713     check_messages( pDP[0], idPlayer, 6, &callbackData );
4714     checkStr( "", callbackData.szTrace1 );
4715     check_messages( pDP[1], idPlayer, 6, &callbackData );
4716     checkStr( "34,", callbackData.szTrace1 );
4717     /* 3 -> g2 */
4718     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[2], 0,
4719                             lpData, dwDataSize );
4720     checkHR( DP_OK, hr );
4721     check_messages( pDP[0], idPlayer, 6, &callbackData );
4722     checkStr( "", callbackData.szTrace1 );
4723     check_messages( pDP[1], idPlayer, 6, &callbackData );
4724     checkStr( "35,34,", callbackData.szTrace1 );
4725
4726     /* 5 -> * */
4727     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], DPID_ALLPLAYERS, 0,
4728                             lpData, dwDataSize );
4729     checkHR( DP_OK, hr );
4730     check_messages( pDP[0], idPlayer, 6, &callbackData );
4731     checkStr( "50,", callbackData.szTrace1 );
4732     check_messages( pDP[1], idPlayer, 6, &callbackData );
4733     checkStr( "54,53,52,51,", callbackData.szTrace1 );
4734     /* 5 -> g0 */
4735     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[0], 0,
4736                             lpData, dwDataSize );
4737     checkHR( DPERR_INVALIDPARAMS, hr );
4738     check_messages( pDP[0], idPlayer, 6, &callbackData );
4739     checkStr( "", callbackData.szTrace1 );
4740     check_messages( pDP[1], idPlayer, 6, &callbackData );
4741     checkStr( "", callbackData.szTrace1 );
4742     /* 5 -> g1 */
4743     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[1], 0,
4744                             lpData, dwDataSize );
4745     checkHR( DP_OK, hr );
4746     check_messages( pDP[0], idPlayer, 6, &callbackData );
4747     checkStr( "", callbackData.szTrace1 );
4748     check_messages( pDP[1], idPlayer, 6, &callbackData );
4749     checkStr( "54,53,", callbackData.szTrace1 );
4750     /* 5 -> g2 */
4751     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[2], 0,
4752                             lpData, dwDataSize );
4753     checkHR( DP_OK, hr );
4754     check_messages( pDP[0], idPlayer, 6, &callbackData );
4755     checkStr( "", callbackData.szTrace1 );
4756     check_messages( pDP[1], idPlayer, 6, &callbackData );
4757     checkStr( "54,", callbackData.szTrace1 );
4758
4759
4760     HeapFree( GetProcessHeap(), 0, lpData );
4761     IDirectPlayX_Release( pDP[0] );
4762     IDirectPlayX_Release( pDP[1] );
4763
4764 }
4765
4766 /* Send */
4767
4768 static void test_Send(void)
4769 {
4770
4771     LPDIRECTPLAY4 pDP[2];
4772     DPSESSIONDESC2 dpsd;
4773     DPID dpid[4], idFrom, idTo;
4774     CallbackData callbackData;
4775     HRESULT hr;
4776     LPCSTR message = "message";
4777     DWORD messageSize = strlen(message) + 1;
4778     DWORD dwDataSize = 1024;
4779     LPDPMSG_GENERIC lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
4780     LPDPMSG_SECUREMESSAGE lpDataSecure;
4781     UINT i;
4782
4783
4784     for (i=0; i<2; i++)
4785     {
4786         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4787                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4788     }
4789     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
4790
4791
4792     /* Uninitialized service provider */
4793     hr = IDirectPlayX_Send( pDP[0], 0, 0, 0,
4794                             (LPVOID) message, messageSize );
4795     checkHR( DPERR_UNINITIALIZED, hr );
4796
4797
4798     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4799     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4800
4801     dpsd.dwSize = sizeof(DPSESSIONDESC2);
4802     dpsd.guidApplication = appGuid;
4803     dpsd.dwMaxPlayers = 10;
4804     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4805     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
4806                                pDP[1], 0 );
4807     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4808
4809
4810     /* Incorrect players */
4811     hr = IDirectPlayX_Send( pDP[0], 0, 1, 2,
4812                             (LPVOID) message, messageSize );
4813     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
4814
4815     if ( hr == DPERR_UNINITIALIZED )
4816     {
4817         todo_wine win_skip( "Send not implemented\n" );
4818         return;
4819     }
4820
4821
4822     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
4823     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
4824     IDirectPlayX_CreatePlayer( pDP[0], &dpid[2], NULL, NULL, NULL, 0, 0 );
4825     IDirectPlayX_CreatePlayer( pDP[1], &dpid[3], NULL, NULL, NULL, 0, 0 );
4826
4827     /* Purge player creation messages */
4828     check_messages( pDP[0], dpid, 4, &callbackData );
4829     checkStr( "S0," "S1,S0," "S2,S1,S0,", callbackData.szTrace1 );
4830     check_messages( pDP[1], dpid, 4, &callbackData );
4831     checkStr( "", callbackData.szTrace1 );
4832
4833
4834     /* Message to self: no error, but no message is sent */
4835     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[0], 0,
4836                             (LPVOID) message, messageSize );
4837     checkHR( DP_OK, hr );
4838
4839     /* Send a message from a remote player */
4840     hr = IDirectPlayX_Send( pDP[1], dpid[0], dpid[1], 0,
4841                             (LPVOID) message, messageSize );
4842     checkHR( DPERR_ACCESSDENIED, hr );
4843     hr = IDirectPlayX_Send( pDP[1], dpid[0], dpid[3], 0,
4844                             (LPVOID) message, messageSize );
4845     checkHR( DPERR_ACCESSDENIED, hr );
4846
4847     /* Null message */
4848     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0,
4849                             NULL, messageSize );
4850     checkHR( DPERR_INVALIDPARAMS, hr );
4851     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0,
4852                             (LPVOID) message, 0 );
4853     checkHR( DPERR_INVALIDPARAMS, hr );
4854
4855
4856     /* Checking no message was sent */
4857     check_messages( pDP[0], dpid, 4, &callbackData );
4858     checkStr( "", callbackData.szTrace1 );
4859     check_messages( pDP[1], dpid, 4, &callbackData );
4860     checkStr( "", callbackData.szTrace1 );
4861
4862
4863     /* Regular parameters */
4864     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4865                             0,
4866                             (LPVOID) message, messageSize );
4867     checkHR( DP_OK, hr );
4868
4869     hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[1],
4870                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4871                                lpData, &dwDataSize );
4872     checkHR( DP_OK, hr );
4873     checkStr( message, (LPSTR) lpData );
4874     check( strlen(message)+1, dwDataSize );
4875
4876     check_messages( pDP[0], dpid, 4, &callbackData );
4877     checkStr( "", callbackData.szTrace1 );
4878     check_messages( pDP[1], dpid, 4, &callbackData );
4879     checkStr( "", callbackData.szTrace1 );
4880
4881
4882     /* Message to a remote player */
4883     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[3], 0,
4884                             (LPVOID) message, messageSize );
4885     checkHR( DP_OK, hr );
4886
4887     hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[3],
4888                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4889                                lpData, &dwDataSize );
4890     checkHR( DPERR_NOMESSAGES, hr );
4891     hr = IDirectPlayX_Receive( pDP[1], &dpid[0], &dpid[3],
4892                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4893                                lpData, &dwDataSize );
4894     checkHR( DP_OK, hr );
4895     checkStr( message, (LPSTR) lpData );
4896     check( strlen(message)+1, dwDataSize );
4897
4898     check_messages( pDP[0], dpid, 4, &callbackData );
4899     checkStr( "", callbackData.szTrace1 );
4900     check_messages( pDP[1], dpid, 4, &callbackData );
4901     checkStr( "", callbackData.szTrace1 );
4902
4903
4904     /* Broadcast */
4905
4906     hr = IDirectPlayX_Send( pDP[0], dpid[0], DPID_ALLPLAYERS, 0,
4907                             (LPVOID) message, messageSize );
4908     checkHR( DP_OK, hr );
4909
4910     for (i=1; i<3; i++)
4911     {
4912         hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[i],
4913                                    DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4914                                    lpData, &dwDataSize );
4915         checkHR( DP_OK, hr );
4916         checkStr( message, (LPSTR) lpData );
4917     }
4918     hr = IDirectPlayX_Receive( pDP[1], &dpid[0], &dpid[3],
4919                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4920                                lpData, &dwDataSize );
4921     checkHR( DP_OK, hr );
4922     checkStr( message, (LPSTR) lpData );
4923
4924     check_messages( pDP[0], dpid, 4, &callbackData );
4925     checkStr( "", callbackData.szTrace1 );
4926     check_messages( pDP[1], dpid, 4, &callbackData );
4927     checkStr( "", callbackData.szTrace1 );
4928
4929
4930     hr = IDirectPlayX_Send( pDP[0], DPID_ALLPLAYERS, dpid[1],
4931                             0,
4932                             (LPVOID) message, messageSize );
4933     checkHR( DPERR_INVALIDPLAYER, hr );
4934     hr = IDirectPlayX_Send( pDP[0], DPID_ALLPLAYERS, DPID_ALLPLAYERS,
4935                             0,
4936                             (LPVOID) message, messageSize );
4937     checkHR( DPERR_INVALIDPLAYER, hr );
4938
4939
4940     /* Flags */
4941     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4942                             DPSEND_GUARANTEED,
4943                             (LPVOID) message, messageSize );
4944     checkHR( DP_OK, hr );
4945
4946     hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[1],
4947                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4948                                lpData, &dwDataSize );
4949     checkHR( DP_OK, hr );
4950     checkStr( message, (LPSTR)lpData );
4951
4952     /* - Inorrect flags */
4953     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4954                             DPSEND_ENCRYPTED,
4955                             (LPVOID) message, messageSize );
4956     checkHR( DPERR_INVALIDPARAMS, hr );
4957     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4958                             DPSEND_SIGNED,
4959                             (LPVOID) message, messageSize );
4960     checkHR( DPERR_INVALIDPARAMS, hr );
4961     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4962                             DPSEND_ENCRYPTED | DPSEND_SIGNED,
4963                             (LPVOID) message, messageSize );
4964     checkHR( DPERR_INVALIDPARAMS, hr );
4965
4966     /* - Correct flags, but session is not secure */
4967     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4968                             DPSEND_ENCRYPTED | DPSEND_GUARANTEED,
4969                             (LPVOID) message, messageSize );
4970     checkHR( DPERR_INVALIDPARAMS, hr );
4971     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4972                             DPSEND_SIGNED | DPSEND_GUARANTEED,
4973                             (LPVOID) message, messageSize );
4974     checkHR( DPERR_INVALIDPARAMS, hr );
4975     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4976                             ( DPSEND_ENCRYPTED |
4977                               DPSEND_SIGNED |
4978                               DPSEND_GUARANTEED ),
4979                             (LPVOID) message, messageSize );
4980     checkHR( DPERR_INVALIDPARAMS, hr );
4981
4982     /* - Corerct flags, secure session incorrectly opened (without flags) */
4983     hr = IDirectPlayX_Close( pDP[0] );
4984     checkHR( DP_OK, hr );
4985
4986     dpsd.dwFlags = 0;
4987     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
4988     checkHR( DP_OK, hr );
4989     for (i=0; i<2; i++)
4990         IDirectPlayX_CreatePlayer( pDP[0], &dpid[i], NULL, NULL, NULL, 0, 0 );
4991
4992     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4993                             DPSEND_ENCRYPTED | DPSEND_GUARANTEED,
4994                             (LPVOID) message, messageSize );
4995     checkHR( DPERR_INVALIDPARAMS, hr );
4996     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4997                             DPSEND_SIGNED | DPSEND_GUARANTEED,
4998                             (LPVOID) message, messageSize );
4999     checkHR( DPERR_INVALIDPARAMS, hr );
5000     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5001                             ( DPSEND_ENCRYPTED |
5002                               DPSEND_SIGNED |
5003                               DPSEND_GUARANTEED ),
5004                             (LPVOID) message, messageSize );
5005     checkHR( DPERR_INVALIDPARAMS, hr );
5006
5007     /* - Correct flags, secure session */
5008     hr = IDirectPlayX_Close( pDP[0] );
5009     checkHR( DP_OK, hr );
5010
5011     dpsd.dwFlags = DPSESSION_SECURESERVER;
5012     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
5013     checkHR( DP_OK, hr );
5014     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
5015     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
5016
5017     /* Purge */
5018     check_messages( pDP[0], dpid, 6, &callbackData );
5019     checkStr( "S0,", callbackData.szTrace1 );
5020
5021
5022     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5023                             DPSEND_ENCRYPTED | DPSEND_GUARANTEED,
5024                             (LPVOID) message, messageSize );
5025     checkHR( DP_OK, hr );
5026     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5027                             DPSEND_SIGNED | DPSEND_GUARANTEED,
5028                             (LPVOID) message, messageSize );
5029     checkHR( DP_OK, hr );
5030     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5031                             ( DPSEND_ENCRYPTED |
5032                               DPSEND_SIGNED |
5033                               DPSEND_GUARANTEED ),
5034                             (LPVOID) message, messageSize );
5035     checkHR( DP_OK, hr );
5036
5037
5038     for (i=0; i<3; i++)
5039     {
5040         dwDataSize = 1024;
5041         hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, 0, lpData,
5042                                    &dwDataSize );
5043
5044         lpDataSecure = (LPDPMSG_SECUREMESSAGE) lpData;
5045
5046         checkHR( DP_OK, hr );
5047         checkConv( DPSYS_SECUREMESSAGE,   lpData->dwType, dpMsgType2str );
5048         check( DPID_SYSMSG,               idFrom );
5049         check( dpid[1],                   idTo );
5050         check( dpid[0],                   lpDataSecure->dpIdFrom );
5051         checkStr( message,        (LPSTR) lpDataSecure->lpData );
5052         check( strlen(message)+1,         lpDataSecure->dwDataSize );
5053
5054         switch(i)
5055         {
5056         case 0:
5057             checkFlags( DPSEND_ENCRYPTED,
5058                         lpDataSecure->dwFlags,
5059                         FLAGS_DPSEND );
5060             break;
5061         case 1:
5062             checkFlags( DPSEND_SIGNED,
5063                         lpDataSecure->dwFlags,
5064                         FLAGS_DPSEND );
5065             break;
5066         case 2:
5067             checkFlags( DPSEND_SIGNED | DPSEND_ENCRYPTED,
5068                         lpDataSecure->dwFlags,
5069                         FLAGS_DPSEND );
5070             break;
5071         default: break;
5072         }
5073     }
5074     check_messages( pDP[0], dpid, 4, &callbackData );
5075     checkStr( "", callbackData.szTrace1 );
5076
5077
5078     /* - Even in a secure session, incorrect flags still not working */
5079     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5080                             DPSEND_ENCRYPTED,
5081                             (LPVOID) message, messageSize );
5082     checkHR( DPERR_INVALIDPARAMS, hr );
5083     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5084                             DPSEND_SIGNED,
5085                             (LPVOID) message, messageSize );
5086     checkHR( DPERR_INVALIDPARAMS, hr );
5087     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5088                             DPSEND_ENCRYPTED | DPSEND_SIGNED,
5089                             (LPVOID) message, messageSize );
5090     checkHR( DPERR_INVALIDPARAMS, hr );
5091
5092
5093     HeapFree( GetProcessHeap(), 0, lpData );
5094     IDirectPlayX_Release( pDP[0] );
5095     IDirectPlayX_Release( pDP[1] );
5096
5097 }
5098
5099 /* Receive */
5100
5101 static void test_Receive(void)
5102 {
5103
5104     LPDIRECTPLAY4 pDP;
5105     DPSESSIONDESC2 dpsd;
5106     DPID dpid[4], idFrom, idTo;
5107     HRESULT hr;
5108     LPCSTR message = "message";
5109     DWORD messageSize = strlen(message) + 1;
5110     DWORD dwDataSize = 1024;
5111     LPDPMSG_GENERIC lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
5112                                         dwDataSize );
5113     LPDPMSG_CREATEPLAYERORGROUP lpDataCreate;
5114     LPDPMSG_DESTROYPLAYERORGROUP lpDataDestroy;
5115
5116     DWORD dwCount;
5117     UINT i;
5118
5119
5120     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5121                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
5122
5123     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5124     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5125     dpsd.guidApplication = appGuid;
5126
5127     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
5128
5129     IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
5130
5131
5132     /* Invalid parameters */
5133     hr = IDirectPlayX_Receive( pDP, NULL, &idTo, 0,
5134                                lpData, &dwDataSize );
5135     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
5136
5137     if ( hr == DPERR_UNINITIALIZED )
5138     {
5139         todo_wine win_skip( "Receive not implemented\n" );
5140         return;
5141     }
5142
5143     hr = IDirectPlayX_Receive( pDP, &idFrom, NULL, 0,
5144                                lpData, &dwDataSize );
5145     checkHR( DPERR_INVALIDPARAMS, hr );
5146     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5147                                lpData, NULL );
5148     checkHR( DPERR_INVALIDPARAMS, hr );
5149     dwDataSize = -1;
5150     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5151                                lpData, &dwDataSize );
5152     checkHR( DPERR_INVALIDPARAMS, hr );
5153
5154     /* No messages yet */
5155     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5156                                NULL, &dwDataSize );
5157     checkHR( DPERR_NOMESSAGES, hr );
5158     dwDataSize = 0;
5159     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5160                                lpData, &dwDataSize );
5161     checkHR( DPERR_NOMESSAGES, hr );
5162
5163
5164     IDirectPlayX_CreatePlayer( pDP, &dpid[0], NULL, 0, NULL, 0, 0 );
5165     IDirectPlayX_CreatePlayer( pDP, &dpid[1], NULL, 0, NULL, 0,
5166                                DPPLAYER_SPECTATOR );
5167     IDirectPlayX_CreatePlayer( pDP, &dpid[2], NULL, 0, NULL, 0, 0 );
5168     IDirectPlayX_CreatePlayer( pDP, &dpid[3], NULL, 0, NULL, 0, 0 );
5169
5170
5171     /* 0, 1, 2, 3 */
5172     /* 3, 2, 1, 0 */
5173     for (i=0; i<4; i++)
5174     {
5175         IDirectPlayX_GetMessageCount( pDP, dpid[i], &dwCount );
5176         check( 3-i, dwCount );
5177     }
5178
5179
5180     IDirectPlayX_DestroyPlayer( pDP, dpid[3] );
5181     IDirectPlayX_DestroyPlayer( pDP, dpid[1] );
5182
5183
5184     /* 0, 1, 2, 3 */
5185     /* 5, 5, 3, 3 */
5186     IDirectPlayX_GetMessageCount( pDP, dpid[0], &dwCount );
5187     check( 5, dwCount );
5188     IDirectPlayX_GetMessageCount( pDP, dpid[1], &dwCount );
5189     check( 5, dwCount );
5190     IDirectPlayX_GetMessageCount( pDP, dpid[2], &dwCount );
5191     check( 3, dwCount );
5192     IDirectPlayX_GetMessageCount( pDP, dpid[3], &dwCount );
5193     check( 3, dwCount );
5194
5195
5196     /* Buffer too small */
5197     hr = IDirectPlayX_Receive( pDP, &idFrom, &idFrom, 0,
5198                                NULL, &dwDataSize );
5199     checkHR( DPERR_BUFFERTOOSMALL, hr );
5200     check( 48, dwDataSize );
5201     dwDataSize = 0;
5202     hr = IDirectPlayX_Receive( pDP, &idTo, &idFrom, 0,
5203                                lpData, &dwDataSize );
5204     checkHR( DPERR_BUFFERTOOSMALL, hr );
5205     check( 48, dwDataSize );
5206
5207
5208     /* Checking the order or reception */
5209     for (i=0; i<11; i++)
5210     {
5211         dwDataSize = 1024;
5212         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5213                                    lpData, &dwDataSize );
5214
5215         checkHR( DP_OK, hr );
5216         check( DPID_SYSMSG, idFrom );
5217
5218         if (i<6)  /* Player creation */
5219         {
5220             checkConv( DPSYS_CREATEPLAYERORGROUP, lpData->dwType, dpMsgType2str );
5221             check( 48, dwDataSize );
5222             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5223             check( DPPLAYERTYPE_PLAYER,   lpDataCreate->dwPlayerType );
5224             checkLP( NULL,                lpDataCreate->lpData );
5225             check( 0,                     lpDataCreate->dwDataSize );
5226             checkLP( NULL,                U1(lpDataCreate->dpnName).lpszShortNameA );
5227             check( 0,                     lpDataCreate->dpIdParent );
5228         }
5229         else  /* Player destruction */
5230         {
5231             checkConv( DPSYS_DESTROYPLAYERORGROUP, lpData->dwType,
5232                        dpMsgType2str );
5233             check( 52, dwDataSize );
5234             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5235             check( DPPLAYERTYPE_PLAYER,   lpDataDestroy->dwPlayerType );
5236             checkLP( NULL,                lpDataDestroy->lpLocalData );
5237             check( 0,                     lpDataDestroy->dwLocalDataSize );
5238             checkLP( NULL,                lpDataDestroy->lpRemoteData );
5239             check( 0,                     lpDataDestroy->dwRemoteDataSize );
5240             checkLP( NULL,                U1(lpDataDestroy->dpnName).lpszShortNameA );
5241             check( 0,                     lpDataDestroy->dpIdParent );
5242         }
5243
5244         switch(i)
5245         {
5246             /* 1 -> 0 */
5247         case 0:
5248             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5249             check( dpid[0], idTo );
5250             check( dpid[1],              lpDataCreate->dpId );
5251             check( 1,                    lpDataCreate->dwCurrentPlayers );
5252             checkFlags( DPPLAYER_LOCAL|DPPLAYER_SPECTATOR, lpDataCreate->dwFlags,
5253                         FLAGS_DPPLAYER|FLAGS_DPGROUP );
5254             break;
5255
5256             /* 2 -> 1,0 */
5257         case 1:
5258             check( dpid[1], idTo );
5259             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5260             check( dpid[2],              lpDataCreate->dpId );
5261             check( 2,                    lpDataCreate->dwCurrentPlayers );
5262             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5263                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5264             break;
5265         case 2:
5266             check( dpid[0], idTo );
5267             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5268             check( dpid[2],              lpDataCreate->dpId );
5269             check( 2,                    lpDataCreate->dwCurrentPlayers );
5270             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5271                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5272             break;
5273
5274             /* 3 -> 2,1,0 */
5275         case 3:
5276             check( dpid[2], idTo );
5277             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5278             check( dpid[3],              lpDataCreate->dpId );
5279             check( 3,                    lpDataCreate->dwCurrentPlayers );
5280             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5281                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5282             break;
5283         case 4:
5284             check( dpid[1], idTo );
5285             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5286             check( dpid[3],              lpDataCreate->dpId );
5287             check( 3,                    lpDataCreate->dwCurrentPlayers );
5288             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5289                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5290             break;
5291         case 5:
5292             check( dpid[0], idTo );
5293             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5294             check( dpid[3],              lpDataCreate->dpId );
5295             check( 3,                    lpDataCreate->dwCurrentPlayers );
5296             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5297                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5298             break;
5299
5300             /* 3 -> 2,1,0 */
5301         case 6:
5302             check( dpid[2], idTo );
5303             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5304             check( dpid[3],              lpDataDestroy->dpId );
5305             checkFlags( DPPLAYER_LOCAL,  lpDataDestroy->dwFlags,
5306                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5307             break;
5308         case 7:
5309             check( dpid[1], idTo );
5310             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5311             check( dpid[3],              lpDataDestroy->dpId );
5312             checkFlags( DPPLAYER_LOCAL,  lpDataDestroy->dwFlags,
5313                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5314             break;
5315         case 8:
5316             check( dpid[0], idTo );
5317             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5318             check( dpid[3],              lpDataDestroy->dpId );
5319             checkFlags( DPPLAYER_LOCAL,  lpDataDestroy->dwFlags,
5320                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5321             break;
5322
5323             /* 1 -> 2,0 */
5324         case 9:
5325             check( dpid[2], idTo );
5326             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5327             check( dpid[1],                 lpDataDestroy->dpId );
5328             checkFlags( DPPLAYER_LOCAL |
5329                         DPPLAYER_SPECTATOR, lpDataDestroy->dwFlags,
5330                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5331             break;
5332         case 10:
5333             check( dpid[0], idTo );
5334             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5335             check( dpid[1],                 lpDataDestroy->dpId );
5336             checkFlags( DPPLAYER_LOCAL |
5337                         DPPLAYER_SPECTATOR, lpDataDestroy->dwFlags,
5338                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5339             break;
5340
5341         default:
5342             trace( "%s\n", dpMsgType2str(lpData->dwType) );
5343             break;
5344         }
5345     }
5346
5347     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpData, &dwDataSize );
5348     checkHR( DPERR_NOMESSAGES, hr );
5349
5350
5351     /* New data message */
5352     hr = IDirectPlayX_Send( pDP, dpid[0], dpid[2], 0,
5353                             (LPVOID) message, messageSize );
5354     checkHR( DP_OK, hr );
5355
5356
5357     /* Ensuring DPRECEIVE_PEEK doesn't remove the messages from the queue */
5358     for (i=0; i<10; i++)
5359     {
5360         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, DPRECEIVE_PEEK,
5361                                    lpData, &dwDataSize );
5362         checkStr( message, (LPSTR) lpData );
5363     }
5364
5365     /* Removing the message from the queue */
5366     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpData, &dwDataSize );
5367     checkHR( DP_OK, hr );
5368     check( idFrom, dpid[0] );
5369     check( idTo, dpid[2] );
5370     checkStr( message, (LPSTR) lpData );
5371
5372     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpData, &dwDataSize );
5373     checkHR( DPERR_NOMESSAGES, hr );
5374
5375
5376     HeapFree( GetProcessHeap(), 0, lpData );
5377     IDirectPlayX_Release( pDP );
5378
5379 }
5380
5381 /* GetMessageCount */
5382
5383 static void test_GetMessageCount(void)
5384 {
5385
5386     LPDIRECTPLAY4 pDP[2];
5387     DPSESSIONDESC2 dpsd;
5388     DPID dpid[4];
5389     HRESULT hr;
5390     UINT i;
5391     DWORD dwCount;
5392
5393     DWORD dwDataSize = 1024;
5394     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
5395     CallbackData callbackData;
5396
5397
5398     for (i=0; i<2; i++)
5399     {
5400         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5401                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
5402     }
5403     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5404
5405     dwCount = -1;
5406     hr = IDirectPlayX_GetMessageCount( pDP[0], 0,  &dwCount );
5407     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
5408     check( -1, dwCount );
5409
5410     if ( hr == DP_OK )
5411     {
5412         todo_wine win_skip( "GetMessageCount not implemented\n" );
5413         return;
5414     }
5415
5416
5417     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
5418     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
5419
5420
5421     dwCount = -1;
5422     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5423     checkHR( DP_OK, hr );
5424     check( 0, dwCount );
5425
5426
5427     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5428     dpsd.guidApplication = appGuid;
5429     dpsd.dwMaxPlayers = 10;
5430     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
5431     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
5432                                pDP[1], 0 );
5433
5434     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
5435     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
5436     IDirectPlayX_CreatePlayer( pDP[1], &dpid[3], NULL, NULL, NULL, 0, 0 );
5437     IDirectPlayX_CreatePlayer( pDP[0], &dpid[2], NULL, NULL, NULL, 0, 0 );
5438
5439
5440     /* Incorrect parameters */
5441     dwCount = -1;
5442     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], NULL );
5443     checkHR( DPERR_INVALIDPARAMS, hr );
5444     check( -1, dwCount );
5445
5446     dwCount = -1;
5447     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, NULL );
5448     checkHR( DPERR_INVALIDPARAMS, hr );
5449     check( -1, dwCount );
5450
5451     dwCount = -1;
5452     hr = IDirectPlayX_GetMessageCount( pDP[0], -1, &dwCount );
5453     checkHR( DPERR_INVALIDPLAYER, hr );
5454     check( -1, dwCount );
5455
5456
5457     /* Correct parameters */
5458     /* Player creation messages */
5459     dwCount = -1;
5460     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5461     checkHR( DP_OK, hr );
5462     check( 5, dwCount );
5463
5464     dwCount = -1;
5465     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5466     checkHR( DP_OK, hr );
5467     check( 1, dwCount );
5468
5469     dwCount = -1;
5470     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
5471     checkHR( DP_OK, hr );
5472     check( 3, dwCount );
5473
5474     dwCount = -1;
5475     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5476     checkHR( DP_OK, hr );
5477     check( 2, dwCount );
5478
5479     dwCount = -1;
5480     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[3], &dwCount );
5481     checkHR( DP_OK, hr );
5482     /* Remote player: doesn't throw error but result is 0 and not 1 */
5483     check( 0, dwCount );
5484
5485     dwCount = -1;
5486     hr = IDirectPlayX_GetMessageCount( pDP[1], dpid[3], &dwCount );
5487     checkHR( DP_OK, hr );
5488     check( 1, dwCount );
5489
5490     dwCount = -1;
5491     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5492     checkHR( DP_OK, hr );
5493     check( 2, dwCount );
5494
5495
5496     /* Purge queues */
5497     check_messages( pDP[0], dpid, 6, &callbackData );
5498     checkStr( "S0,S1,S0,S1,S0,", callbackData.szTrace1 );
5499     check_messages( pDP[1], dpid, 6, &callbackData );
5500     checkStr( "S3,", callbackData.szTrace1 );
5501
5502
5503     /* Ensure queues is purged */
5504     dwCount = -1;
5505     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5506     checkHR( DP_OK, hr );
5507     check( 0, dwCount );
5508
5509     dwCount = -1;
5510     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5511     checkHR( DP_OK, hr );
5512     check( 0, dwCount );
5513
5514
5515     /* Send data messages */
5516     for (i=0; i<5; i++)
5517         IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0, lpData, dwDataSize );
5518     for (i=0; i<6; i++)
5519         IDirectPlayX_Send( pDP[0], dpid[1], dpid[2], 0, lpData, dwDataSize );
5520     for (i=0; i<7; i++)
5521         IDirectPlayX_Send( pDP[0], dpid[2], dpid[3], 0, lpData, dwDataSize );
5522
5523
5524     /* Check all messages are in the queues */
5525     dwCount = -1;
5526     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5527     checkHR( DP_OK, hr );
5528     check( 11, dwCount );
5529
5530     dwCount = -1;
5531     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5532     checkHR( DP_OK, hr );
5533     check( 7, dwCount );
5534
5535     dwCount = -1;
5536     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
5537     checkHR( DP_OK, hr );
5538     check( 0, dwCount );
5539
5540     dwCount = -1;
5541     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5542     checkHR( DP_OK, hr );
5543     check( 5, dwCount );
5544
5545     dwCount = -1;
5546     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[2], &dwCount );
5547     checkHR( DP_OK, hr );
5548     check( 6, dwCount );
5549
5550     dwCount = -1;
5551     hr = IDirectPlayX_GetMessageCount( pDP[1], dpid[3], &dwCount );
5552     checkHR( DP_OK, hr );
5553     check( 7, dwCount );
5554
5555
5556     /* Purge queues again */
5557     check_messages( pDP[0], dpid, 6, &callbackData );
5558     checkStr( "01,01,01,01,01,"
5559               "12,12,12,12,12,12,", callbackData.szTrace1 );
5560     check_messages( pDP[1], dpid, 6, &callbackData );
5561     checkStr( "23,23,23,23,23,23,23,", callbackData.szTrace1 );
5562
5563
5564     /* Check queues are purged */
5565     dwCount = -1;
5566     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5567     checkHR( DP_OK, hr );
5568     check( 0, dwCount );
5569
5570     dwCount = -1;
5571     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5572     checkHR( DP_OK, hr );
5573     check( 0, dwCount );
5574
5575     dwCount = -1;
5576     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
5577     checkHR( DP_OK, hr );
5578     check( 0, dwCount );
5579
5580     dwCount = -1;
5581     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5582     checkHR( DP_OK, hr );
5583     check( 0, dwCount );
5584
5585     dwCount = -1;
5586     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[2], &dwCount );
5587     checkHR( DP_OK, hr );
5588     check( 0, dwCount );
5589
5590     dwCount = -1;
5591     hr = IDirectPlayX_GetMessageCount( pDP[1], dpid[3], &dwCount );
5592     checkHR( DP_OK, hr );
5593     check( 0, dwCount );
5594
5595
5596     HeapFree( GetProcessHeap(), 0, lpData );
5597     IDirectPlayX_Release( pDP[0] );
5598     IDirectPlayX_Release( pDP[1] );
5599
5600 }
5601
5602 /* GetMessageQueue */
5603
5604 static void test_GetMessageQueue(void)
5605 {
5606
5607     LPDIRECTPLAY4 pDP[2];
5608     DPSESSIONDESC2 dpsd;
5609     DPID dpid[4];
5610     CallbackData callbackData;
5611     HRESULT hr;
5612     UINT i;
5613     DWORD dwNumMsgs, dwNumBytes;
5614
5615     DWORD dwDataSize = 1024;
5616     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
5617
5618
5619     for (i=0; i<2; i++)
5620     {
5621         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5622                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
5623     }
5624     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5625
5626
5627     dwNumMsgs = dwNumBytes = -1;
5628     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0, 0,
5629                                        &dwNumMsgs, &dwNumBytes );
5630     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
5631     check( -1, dwNumMsgs );
5632     check( -1, dwNumBytes );
5633
5634     if ( hr == DP_OK )
5635     {
5636         todo_wine win_skip( "GetMessageQueue not implemented\n" );
5637         return;
5638     }
5639
5640
5641     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
5642     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
5643
5644
5645     dwNumMsgs = dwNumBytes = -1;
5646     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0, 0,
5647                                        &dwNumMsgs, &dwNumBytes );
5648     checkHR( DP_OK, hr );
5649     check( 0, dwNumMsgs );
5650     check( 0, dwNumBytes );
5651
5652
5653     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5654     dpsd.guidApplication = appGuid;
5655     dpsd.dwMaxPlayers = 10;
5656     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
5657     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
5658                                pDP[1], 0 );
5659
5660     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
5661     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
5662     IDirectPlayX_CreatePlayer( pDP[1], &dpid[3], NULL, NULL, NULL, 0, 0 );
5663     IDirectPlayX_CreatePlayer( pDP[0], &dpid[2], NULL, NULL, NULL, 0, 0 );
5664
5665
5666
5667     /* Incorrect parameters */
5668     dwNumMsgs = dwNumBytes = -1;
5669     hr = IDirectPlayX_GetMessageQueue( pDP[0], -1, dpid[1],
5670                                        0,
5671                                        &dwNumMsgs, &dwNumBytes );
5672     checkHR( DPERR_INVALIDPLAYER, hr );
5673     check( -1, dwNumMsgs );
5674     check( -1, dwNumBytes );
5675
5676     dwNumMsgs = dwNumBytes = -1;
5677     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], -1,
5678                                        0,
5679                                        &dwNumMsgs, &dwNumBytes );
5680     checkHR( DPERR_INVALIDPLAYER, hr );
5681     check( -1, dwNumMsgs );
5682     check( -1, dwNumBytes );
5683
5684     dwNumMsgs = dwNumBytes = -1;
5685     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[0],
5686                                        -1,
5687                                        &dwNumMsgs, &dwNumBytes );
5688     checkHR( DPERR_INVALIDFLAGS, hr );
5689     check( -1, dwNumMsgs );
5690     check( -1, dwNumBytes );
5691
5692     dwNumMsgs = dwNumBytes = -1;
5693     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5694                                        ( DPMESSAGEQUEUE_SEND |
5695                                          DPMESSAGEQUEUE_RECEIVE ),
5696                                        &dwNumMsgs, &dwNumBytes );
5697     checkHR( DPERR_INVALIDFLAGS, hr );
5698     check( -1, dwNumMsgs );
5699     check( -1, dwNumBytes );
5700
5701     /* - Remote players */
5702     dwNumMsgs = dwNumBytes = -1;
5703     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, dpid[3],
5704                                        DPMESSAGEQUEUE_RECEIVE,
5705                                        &dwNumMsgs, &dwNumBytes );
5706     checkHR( DPERR_INVALIDPLAYER, hr ); /* Player 3 is remote */
5707     check( -1, dwNumMsgs );
5708     check( -1, dwNumBytes );
5709
5710     dwNumMsgs = dwNumBytes = -1;
5711     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[3], 0,
5712                                        DPMESSAGEQUEUE_SEND,
5713                                        &dwNumMsgs, &dwNumBytes );
5714     checkHR( DPERR_INVALIDPLAYER, hr ); /* Player 3 is remote */
5715     check( -1, dwNumMsgs );
5716     check( -1, dwNumBytes );
5717
5718     /* - Remote players, this time in the right place */
5719     dwNumMsgs = dwNumBytes = -1;
5720     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, dpid[3],
5721                                        DPMESSAGEQUEUE_SEND,
5722                                        &dwNumMsgs, &dwNumBytes );
5723     checkHR( DP_OK, hr );
5724     check( 0, dwNumMsgs );
5725     check( 0, dwNumBytes );
5726
5727     dwNumMsgs = dwNumBytes = -1;
5728     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[3], 0,
5729                                        DPMESSAGEQUEUE_RECEIVE,
5730                                        &dwNumMsgs, &dwNumBytes );
5731     checkHR( DP_OK, hr );
5732     check( 0, dwNumMsgs );
5733     check( 0, dwNumBytes );
5734
5735
5736     /* Correct parameters */
5737     dwNumMsgs = dwNumBytes = -1;
5738     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, dpid[1],
5739                                        DPMESSAGEQUEUE_RECEIVE,
5740                                        &dwNumMsgs, &dwNumBytes );
5741     checkHR( DP_OK, hr );
5742     check( 2, dwNumMsgs );
5743     check( 96, dwNumBytes );
5744
5745     dwNumMsgs = dwNumBytes = -1;
5746     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], 0,
5747                                        DPMESSAGEQUEUE_RECEIVE,
5748                                        &dwNumMsgs, &dwNumBytes );
5749     checkHR( DP_OK, hr );
5750     check( 0, dwNumMsgs );
5751     check( 0, dwNumBytes );
5752
5753     dwNumMsgs = dwNumBytes = -1;
5754     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0,
5755                                        DPMESSAGEQUEUE_RECEIVE,
5756                                        &dwNumMsgs, &dwNumBytes );
5757     checkHR( DP_OK, hr );
5758     check( 5, dwNumMsgs );
5759     check( 240, dwNumBytes );
5760
5761     dwNumMsgs = dwNumBytes = -1;
5762     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5763                                        DPMESSAGEQUEUE_RECEIVE,
5764                                        NULL, &dwNumBytes );
5765     checkHR( DP_OK, hr );
5766     check( -1, dwNumMsgs );
5767     check( 0, dwNumBytes );
5768
5769     dwNumMsgs = dwNumBytes = -1;
5770     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5771                                        DPMESSAGEQUEUE_RECEIVE,
5772                                        &dwNumMsgs, NULL );
5773     checkHR( DP_OK, hr );
5774     check( 0, dwNumMsgs );
5775     check( -1, dwNumBytes );
5776
5777     dwNumMsgs = dwNumBytes = -1;
5778     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5779                                        DPMESSAGEQUEUE_RECEIVE,
5780                                        NULL, NULL );
5781     checkHR( DP_OK, hr );
5782     check( -1, dwNumMsgs );
5783     check( -1, dwNumBytes );
5784
5785     dwNumMsgs = dwNumBytes = -1;
5786     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5787                                        DPMESSAGEQUEUE_RECEIVE,
5788                                        &dwNumMsgs, &dwNumBytes );
5789     checkHR( DP_OK, hr );
5790     check( 0, dwNumMsgs );
5791     check( 0, dwNumBytes );
5792
5793
5794     /* Purge messages */
5795     check_messages( pDP[0], dpid, 6, &callbackData );
5796     checkStr( "S0,S1,S0,S1,S0,", callbackData.szTrace1 );
5797     check_messages( pDP[1], dpid, 6, &callbackData );
5798     checkStr( "S3,", callbackData.szTrace1 );
5799
5800     /* Check queues are empty */
5801     dwNumMsgs = dwNumBytes = -1;
5802     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0,
5803                                        DPMESSAGEQUEUE_RECEIVE,
5804                                        &dwNumMsgs, &dwNumBytes );
5805     checkHR( DP_OK, hr );
5806     check( 0, dwNumMsgs );
5807     check( 0, dwNumBytes );
5808
5809
5810     /* Sending 4 data messages from 0 to 1 */
5811     /*         3               from 0 to 3 */
5812     /*         2               from 1 to 3 */
5813     for (i=0; i<4; i++)
5814         IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0, lpData, dwDataSize );
5815     for (i=0; i<3; i++)
5816         IDirectPlayX_Send( pDP[0], dpid[0], dpid[3], 0, lpData, dwDataSize );
5817     for (i=0; i<2; i++)
5818         IDirectPlayX_Send( pDP[0], dpid[1], dpid[3], 0, lpData, dwDataSize );
5819
5820
5821     dwNumMsgs = dwNumBytes = -1;
5822     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5823                                        DPMESSAGEQUEUE_RECEIVE,
5824                                        &dwNumMsgs, &dwNumBytes );
5825     checkHR( DP_OK, hr );
5826     check( 4, dwNumMsgs );
5827     check( 4*dwDataSize, dwNumBytes );
5828
5829     dwNumMsgs = dwNumBytes = -1;
5830     hr = IDirectPlayX_GetMessageQueue( pDP[1], dpid[0], dpid[3],
5831                                        DPMESSAGEQUEUE_RECEIVE,
5832                                        &dwNumMsgs, &dwNumBytes );
5833     checkHR( DP_OK, hr );
5834     check( 3, dwNumMsgs );
5835     check( 3*dwDataSize, dwNumBytes );
5836
5837     dwNumMsgs = dwNumBytes = -1;
5838     hr = IDirectPlayX_GetMessageQueue( pDP[1], dpid[1], dpid[3],
5839                                        DPMESSAGEQUEUE_RECEIVE,
5840                                        &dwNumMsgs, &dwNumBytes );
5841     checkHR( DP_OK, hr );
5842     check( 2, dwNumMsgs );
5843     check( 2*dwDataSize, dwNumBytes );
5844
5845     dwNumMsgs = dwNumBytes = -1;
5846     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], 0,
5847                                        DPMESSAGEQUEUE_RECEIVE,
5848                                        &dwNumMsgs, &dwNumBytes );
5849     checkHR( DP_OK, hr );
5850     check( 4, dwNumMsgs );
5851     check( 4*dwDataSize, dwNumBytes );
5852
5853     dwNumMsgs = dwNumBytes = -1;
5854     hr = IDirectPlayX_GetMessageQueue( pDP[1], dpid[0], 0,
5855                                        DPMESSAGEQUEUE_RECEIVE,
5856                                        &dwNumMsgs, &dwNumBytes );
5857     checkHR( DP_OK, hr );
5858     check( 3, dwNumMsgs );
5859     check( 3*dwDataSize, dwNumBytes );
5860
5861     dwNumMsgs = dwNumBytes = -1;
5862     hr = IDirectPlayX_GetMessageQueue( pDP[1], 0, dpid[3],
5863                                        DPMESSAGEQUEUE_RECEIVE,
5864                                        &dwNumMsgs, &dwNumBytes );
5865     checkHR( DP_OK, hr );
5866     check( 5, dwNumMsgs );
5867     check( 5*dwDataSize, dwNumBytes );
5868
5869     dwNumMsgs = dwNumBytes = -1;
5870     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0,
5871                                        DPMESSAGEQUEUE_RECEIVE,
5872                                        &dwNumMsgs, &dwNumBytes );
5873     checkHR( DP_OK, hr );
5874     check( 4, dwNumMsgs );
5875     check( 4*dwDataSize, dwNumBytes );
5876
5877     dwNumMsgs = dwNumBytes = -1;
5878     hr = IDirectPlayX_GetMessageQueue( pDP[1], 0, 0,
5879                                        DPMESSAGEQUEUE_RECEIVE,
5880                                        &dwNumMsgs, &dwNumBytes );
5881     checkHR( DP_OK, hr );
5882     check( 5, dwNumMsgs );
5883     check( 5*dwDataSize, dwNumBytes );
5884
5885
5886     dwNumMsgs = dwNumBytes = -1;
5887     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5888                                        DPMESSAGEQUEUE_SEND,
5889                                        &dwNumMsgs, &dwNumBytes );
5890     checkHR( DP_OK, hr );
5891     check( 0, dwNumMsgs );
5892     check( 0, dwNumBytes );
5893
5894     dwNumMsgs = dwNumBytes = -1;
5895     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5896                                        0,
5897                                        &dwNumMsgs, &dwNumBytes );
5898     checkHR( DP_OK, hr );
5899     check( 0, dwNumMsgs );
5900     check( 0, dwNumBytes );
5901
5902
5903     HeapFree( GetProcessHeap(), 0, lpData );
5904     IDirectPlayX_Release( pDP[0] );
5905     IDirectPlayX_Release( pDP[1] );
5906
5907 }
5908
5909 /* Remote data replication */
5910
5911 static void test_remote_data_replication(void)
5912 {
5913
5914     LPDIRECTPLAY4 pDP[2];
5915     DPSESSIONDESC2 dpsd;
5916     DPID dpid[2], idFrom, idTo;
5917     CallbackData callbackData;
5918     HRESULT hr;
5919     UINT i, j;
5920     DWORD dwFlags, dwDataSize = 1024;
5921     DWORD dwCount;
5922
5923     LPDPMSG_SETPLAYERORGROUPDATA lpData = HeapAlloc( GetProcessHeap(),
5924                                                      HEAP_ZERO_MEMORY,
5925                                                      dwDataSize );
5926
5927     LPCSTR lpDataLocal[] = { "local_0", "local_1" };
5928     LPCSTR lpDataRemote[] = { "remote_0", "remote_1" };
5929     LPCSTR lpDataFake = "ugly_fake_data";
5930     LPSTR lpDataGet = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 32 );
5931     DWORD dwDataSizeLocal = strlen(lpDataLocal[0])+1,
5932         dwDataSizeRemote = strlen(lpDataRemote[0])+1,
5933         dwDataSizeFake = strlen(lpDataFake)+1,
5934         dwDataSizeGet;
5935
5936
5937     for (i=0; i<2; i++)
5938     {
5939         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5940                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
5941         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
5942     }
5943     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5944     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5945     dpsd.guidApplication = appGuid;
5946
5947     /* Host */
5948     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
5949     todo_wine checkHR( DP_OK, hr );
5950
5951     if ( hr == DPERR_UNINITIALIZED )
5952     {
5953         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
5954         return;
5955     }
5956
5957     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
5958                                     NULL, NULL, NULL, 0, 0 );
5959     checkHR( DP_OK, hr );
5960
5961     /* Peer */
5962     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
5963                                     pDP[1], 0 );
5964     checkHR( DP_OK, hr );
5965
5966     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
5967                                     NULL, NULL, NULL, 0, 0 );
5968     checkHR( DP_OK, hr );
5969
5970     /* Check players */
5971     for (i=0; i<2; i++)
5972     {
5973         /* Local (0,0) (1,1) */
5974         IDirectPlayX_GetPlayerFlags( pDP[i], dpid[i], &dwFlags );
5975         checkFlags( DPPLAYER_LOCAL, dwFlags, FLAGS_DPPLAYER );
5976         /* Remote (0,1) (1,0) */
5977         IDirectPlayX_GetPlayerFlags( pDP[i], dpid[!i], &dwFlags );
5978         checkFlags( 0, dwFlags, FLAGS_DPPLAYER );
5979     }
5980
5981     /* Set data for a local player */
5982     for (i=0; i<2; i++)
5983     {
5984         hr = IDirectPlayX_SetPlayerData( pDP[i], dpid[i],
5985                                          (LPVOID) lpDataLocal[i],
5986                                          dwDataSizeLocal,
5987                                          DPSET_LOCAL );
5988         checkHR( DP_OK, hr );
5989         hr = IDirectPlayX_SetPlayerData( pDP[i], dpid[i],
5990                                          (LPVOID) lpDataRemote[i],
5991                                          dwDataSizeRemote,
5992                                          DPSET_REMOTE );
5993         checkHR( DP_OK, hr );
5994     }
5995
5996     /* Retrieve data locally (0->0, 1->1) */
5997     for (i=0; i<2; i++)
5998     {
5999         dwDataSizeGet = dwDataSizeFake;
6000         strcpy( lpDataGet, lpDataFake );
6001         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[i],
6002                                          lpDataGet, &dwDataSizeGet,
6003                                          DPGET_LOCAL );
6004         checkHR( DP_OK, hr );
6005         check( dwDataSizeLocal, dwDataSizeGet );
6006         checkStr( lpDataLocal[i], lpDataGet );
6007
6008         dwDataSizeGet = dwDataSizeFake;
6009         strcpy( lpDataGet, lpDataFake );
6010         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[i],
6011                                          lpDataGet, &dwDataSizeGet,
6012                                          DPGET_REMOTE );
6013         checkHR( DP_OK, hr );
6014         check( dwDataSizeRemote, dwDataSizeGet );
6015         checkStr( lpDataRemote[i], lpDataGet );
6016     }
6017
6018
6019     /* Set data for a remote player */
6020     /* This should fail with DPERR_ACCESSDENIED,
6021        but for some reason it doesn't */
6022     for (i=0; i<2; i++)
6023     {
6024         IDirectPlayX_SetPlayerData( pDP[i], dpid[!i],
6025                                     (LPVOID) lpDataLocal[!i],
6026                                     dwDataSizeLocal,
6027                                     DPSET_LOCAL );
6028         checkHR( DP_OK, hr );
6029         IDirectPlayX_SetPlayerData( pDP[i], dpid[!i],
6030                                     (LPVOID) lpDataRemote[!i],
6031                                     dwDataSizeRemote,
6032                                     DPSET_REMOTE );
6033         checkHR( DP_OK, hr );
6034     }
6035
6036     /* Retrieve crossed data (0->1, 1->0) */
6037     for (i=0; i<2; i++)
6038     {
6039         dwDataSizeGet = dwDataSizeFake;
6040         strcpy( lpDataGet, lpDataFake );
6041         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[!i],
6042                                          lpDataGet, &dwDataSizeGet,
6043                                          DPGET_LOCAL );
6044         checkHR( DP_OK, hr );
6045         check( dwDataSizeLocal, dwDataSizeGet );
6046         checkStr( lpDataLocal[!i], lpDataGet );
6047
6048         dwDataSizeGet = dwDataSizeFake;
6049         strcpy( lpDataGet, lpDataFake );
6050         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[!i],
6051                                          lpDataGet, &dwDataSizeGet,
6052                                          DPGET_REMOTE );
6053         checkHR( DP_OK, hr );
6054         check( dwDataSizeRemote, dwDataSizeGet );
6055         checkStr( lpDataRemote[!i], lpDataGet );
6056     }
6057
6058
6059     /* Purge "new player" messages from queue */
6060     hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, 0, lpData, &dwDataSize );
6061     checkHR( DP_OK, hr );
6062     checkConv( DPSYS_CREATEPLAYERORGROUP, lpData->dwType, dpMsgType2str );
6063
6064     /* Check number of messages in queue */
6065     for (i=0; i<2; i++)
6066     {
6067         IDirectPlayX_GetMessageCount( pDP[i], dpid[i], &dwCount );
6068         check( 2, dwCount );
6069         IDirectPlayX_GetMessageCount( pDP[i], dpid[!i], &dwCount );
6070         check( 0, dwCount );
6071     }
6072
6073     /* Checking system messages */
6074     for (i=0; i<2; i++)
6075     {
6076         for (j=0; j<2; j++)
6077         {
6078             hr = IDirectPlayX_Receive( pDP[i], &idFrom, &idTo, 0, lpData,
6079                                        &dwDataSize );
6080             checkHR( DP_OK, hr );
6081             check( 29, dwDataSize );
6082             check( DPID_SYSMSG, idFrom );
6083             check( dpid[i], idTo );
6084             checkConv( DPSYS_SETPLAYERORGROUPDATA, lpData->dwType,
6085                        dpMsgType2str );
6086             check( DPPLAYERTYPE_PLAYER,            lpData->dwPlayerType );
6087             check( dpid[j],                        lpData->dpId );
6088             checkStr( lpDataRemote[j],     (LPSTR) lpData->lpData );
6089             check( dwDataSizeRemote,               lpData->dwDataSize );
6090             dwDataSize = 1024;
6091         }
6092         hr = IDirectPlayX_Receive( pDP[i], &idFrom, &idTo, 0,
6093                                    lpData, &dwDataSize );
6094         checkHR( DPERR_NOMESSAGES, hr );
6095     }
6096
6097
6098     /* Changing remote data */
6099     hr = IDirectPlayX_SetPlayerData( pDP[0], dpid[0],
6100                                      (LPVOID) lpDataRemote[0], dwDataSizeRemote,
6101                                      DPSET_REMOTE );
6102     checkHR( DP_OK, hr );
6103
6104     /* Checking system messages (j=0) */
6105     for (i=0; i<2; i++)
6106     {
6107         hr = IDirectPlayX_Receive( pDP[i], &idFrom, &idTo, 0,
6108                                    lpData, &dwDataSize );
6109         checkHR( DP_OK, hr );
6110         check( 29, dwDataSize );
6111         check( DPID_SYSMSG, idFrom );
6112         check( dpid[i], idTo );
6113         checkConv( DPSYS_SETPLAYERORGROUPDATA, lpData->dwType, dpMsgType2str );
6114         check( DPPLAYERTYPE_PLAYER,            lpData->dwPlayerType );
6115         check( dpid[0],                        lpData->dpId );
6116         checkStr( lpDataRemote[0],     (LPSTR) lpData->lpData );
6117         check( dwDataSizeRemote,               lpData->dwDataSize );
6118         dwDataSize = 1024;
6119     }
6120
6121     /* Queue is empty */
6122     check_messages( pDP[0], dpid, 2, &callbackData );
6123     checkStr( "", callbackData.szTrace1 );
6124     check_messages( pDP[1], dpid, 2, &callbackData );
6125     checkStr( "", callbackData.szTrace1 );
6126
6127
6128     HeapFree( GetProcessHeap(), 0, lpDataGet );
6129     HeapFree( GetProcessHeap(), 0, lpData );
6130     IDirectPlayX_Release( pDP[0] );
6131     IDirectPlayX_Release( pDP[1] );
6132
6133 }
6134
6135 /* Host migration */
6136
6137 static void test_host_migration(void)
6138 {
6139
6140     LPDIRECTPLAY4 pDP[2];
6141     DPSESSIONDESC2 dpsd;
6142     DPID dpid[2], idFrom, idTo;
6143     HRESULT hr;
6144     UINT i;
6145     DWORD dwCount;
6146
6147     DWORD dwDataSize = 1024;
6148     LPDPMSG_DESTROYPLAYERORGROUP lpData = HeapAlloc( GetProcessHeap(),
6149                                                      HEAP_ZERO_MEMORY,
6150                                                      dwDataSize );
6151
6152
6153     for (i=0; i<2; i++)
6154     {
6155         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
6156                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
6157         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
6158     }
6159     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
6160     dpsd.dwSize = sizeof(DPSESSIONDESC2);
6161     dpsd.guidApplication = appGuid;
6162     dpsd.dwMaxPlayers = 10;
6163     dpsd.dwFlags = DPSESSION_MIGRATEHOST;
6164
6165     /* Host */
6166     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
6167     todo_wine checkHR( DP_OK, hr );
6168
6169     if ( hr != DP_OK )
6170     {
6171         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
6172         return;
6173     }
6174
6175     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
6176     checkHR( DP_OK, hr );
6177
6178     /* Peer */
6179     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
6180                                     pDP[1], 0 );
6181     checkHR( DP_OK, hr );
6182
6183     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1], NULL, NULL, NULL, 0, 0 );
6184     checkHR( DP_OK, hr );
6185
6186
6187     /* Host: One message in queue */
6188     IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
6189     check( 1, dwCount );
6190     dwDataSize = 1024;
6191     hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, DPRECEIVE_PEEK,
6192                                lpData, &dwDataSize );
6193     checkHR( DP_OK, hr );
6194     checkConv( DPSYS_CREATEPLAYERORGROUP, lpData->dwType, dpMsgType2str );
6195
6196     /* Peer: No messages */
6197     IDirectPlayX_GetMessageCount( pDP[1], dpid[1], &dwCount );
6198     check( 0, dwCount );
6199     hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, DPRECEIVE_PEEK,
6200                                lpData, &dwDataSize );
6201     checkHR( DPERR_NOMESSAGES, hr );
6202
6203
6204     /* Closing host */
6205     IDirectPlayX_Close( pDP[0] );
6206
6207
6208     /* Host: Queue is cleaned */
6209     IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
6210     check( 0, dwCount );
6211     hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, DPRECEIVE_PEEK,
6212                                lpData, &dwDataSize );
6213     checkHR( DPERR_NOMESSAGES, hr );
6214
6215     /* Peer: gets message of player destruction */
6216     IDirectPlayX_GetMessageCount( pDP[1], dpid[1], &dwCount );
6217     check( 2, dwCount );
6218     dwDataSize = 1024;
6219     hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, DPRECEIVE_PEEK,
6220                                lpData, &dwDataSize );
6221     checkHR( DP_OK, hr );
6222     checkConv( DPSYS_DESTROYPLAYERORGROUP, lpData->dwType, dpMsgType2str );
6223
6224
6225     /* Message analysis */
6226     for (i=0; i<2; i++)
6227     {
6228         hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, 0,
6229                                    lpData, &dwDataSize );
6230         checkHR( DP_OK, hr );
6231         check( DPID_SYSMSG, idFrom );
6232         check( dpid[1], idTo ); /* Peer player id */
6233         switch(i)
6234         {
6235         case 0:
6236             checkConv( DPSYS_DESTROYPLAYERORGROUP, lpData->dwType,
6237                        dpMsgType2str );
6238             check( DPPLAYERTYPE_PLAYER, lpData->dwPlayerType );
6239             check( dpid[0],             lpData->dpId ); /* Host player id */
6240             checkLP( NULL,              lpData->lpLocalData );
6241             check( 0,                   lpData->dwLocalDataSize );
6242             checkLP( NULL,              lpData->lpRemoteData );
6243             check( 0,                   lpData->dwRemoteDataSize );
6244             checkLP( NULL,              U1(lpData->dpnName).lpszShortNameA );
6245             check( 0,                   lpData->dpIdParent );
6246             checkFlags( 0,              lpData->dwFlags,
6247                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
6248             break;
6249         case 1:
6250             checkConv( DPSYS_HOST, lpData->dwType, dpMsgType2str );
6251             break;
6252         default:
6253             break;
6254         }
6255         dwDataSize = 1024;
6256     }
6257     hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, 0, lpData, &dwDataSize );
6258     checkHR( DPERR_NOMESSAGES, hr );
6259
6260
6261     HeapFree( GetProcessHeap(), 0, lpData );
6262     IDirectPlayX_Release( pDP[0] );
6263     IDirectPlayX_Release( pDP[1] );
6264
6265 }
6266
6267
6268 START_TEST(dplayx)
6269 {
6270     if (!winetest_interactive)
6271     {
6272         skip("Run in interactive mode to run dplayx tests.\n");
6273         return;
6274     }
6275
6276     CoInitialize( NULL );
6277
6278     trace("Running in interactive mode, tests will take a while\n");
6279
6280     test_DirectPlayCreate();
6281     test_EnumConnections();
6282     test_InitializeConnection();
6283
6284     test_GetCaps();
6285     /* test_Open() takes almost a minute, */
6286     test_Open();
6287     /* test_EnumSession takes three minutes */
6288     test_EnumSessions();
6289     test_SessionDesc();
6290
6291     /* test_CreatePlayer() takes over a minute */
6292     test_CreatePlayer();
6293     test_GetPlayerCaps();
6294     test_PlayerData();
6295     test_PlayerName();
6296
6297     /* test_GetPlayerAccount() takes over 30s */
6298     test_GetPlayerAccount();
6299     test_GetPlayerAddress();
6300     test_GetPlayerFlags();
6301
6302     test_CreateGroup();
6303     test_GroupOwner();
6304
6305     test_EnumPlayers();
6306     test_EnumGroups();
6307     test_EnumGroupsInGroup();
6308
6309     test_groups_p2p();
6310     test_groups_cs();
6311
6312     test_Send();
6313     test_Receive();
6314     test_GetMessageCount();
6315     test_GetMessageQueue();
6316
6317     test_remote_data_replication();
6318     test_host_migration();
6319
6320     CoUninitialize();
6321 }