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