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