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