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