gdi32: Add get_pixel primitives.
[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
2529     /* - Local (no propagation) */
2530     U1(playerName).lpszShortNameA = (LPSTR) "no_propagation";
2531     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2532                                      DPSET_LOCAL );
2533     checkHR( DP_OK, hr );
2534
2535     dwDataSize = 1024;
2536     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0],
2537                                      lpData, &dwDataSize ); /* Local fetch */
2538     checkHR( DP_OK, hr );
2539     check( 48, dwDataSize );
2540     checkStr( "no_propagation", U1(*(LPDPNAME)lpData).lpszShortNameA );
2541
2542     dwDataSize = 1024;
2543     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2544                                      lpData, &dwDataSize ); /* Remote fetch */
2545     checkHR( DP_OK, hr );
2546     check( 45, dwDataSize );
2547     checkStr( "player_name", U1(*(LPDPNAME)lpData).lpszShortNameA );
2548
2549     /* -- 2 */
2550
2551     U1(playerName).lpszShortNameA = (LPSTR) "no_propagation_2";
2552     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2553                                      DPSET_LOCAL | DPSET_REMOTE );
2554     checkHR( DP_OK, hr );
2555
2556     dwDataSize = 1024;
2557     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0],
2558                                      lpData, &dwDataSize ); /* Local fetch */
2559     checkHR( DP_OK, hr );
2560     check( 50, dwDataSize );
2561     checkStr( "no_propagation_2", U1(*(LPDPNAME)lpData).lpszShortNameA );
2562
2563     dwDataSize = 1024;
2564     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2565                                      lpData, &dwDataSize ); /* Remote fetch */
2566     checkHR( DP_OK, hr );
2567     check( 45, dwDataSize );
2568     checkStr( "player_name", U1(*(LPDPNAME)lpData).lpszShortNameA );
2569
2570     /* - Remote (propagation, default) */
2571     U1(playerName).lpszShortNameA = (LPSTR) "propagation";
2572     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2573                                      DPSET_REMOTE );
2574     checkHR( DP_OK, hr );
2575
2576     dwDataSize = 1024;
2577     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2578                                      lpData, &dwDataSize ); /* Remote fetch */
2579     checkHR( DP_OK, hr );
2580     check( 45, dwDataSize );
2581     checkStr( "propagation", U1(*(LPDPNAME)lpData).lpszShortNameA );
2582
2583     /* -- 2 */
2584     U1(playerName).lpszShortNameA = (LPSTR) "propagation_2";
2585     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2586                                      0 );
2587     checkHR( DP_OK, hr );
2588
2589     dwDataSize = 1024;
2590     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2591                                      lpData, &dwDataSize ); /* Remote fetch */
2592     checkHR( DP_OK, hr );
2593     check( 47, dwDataSize );
2594     checkStr( "propagation_2", U1(*(LPDPNAME)lpData).lpszShortNameA );
2595
2596
2597     /* Checking system messages */
2598     check_messages( pDP[0], dpid, 2, &callbackData );
2599     checkStr( "S0,S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
2600     checkStr( "48,28,57,28,57,57,59,", callbackData.szTrace2 );
2601     check_messages( pDP[1], dpid, 2, &callbackData );
2602     checkStr( "S1,S1,S1,S1,S1,S1,", callbackData.szTrace1 );
2603     checkStr( "28,57,28,57,57,59,", callbackData.szTrace2 );
2604
2605
2606     HeapFree( GetProcessHeap(), 0, lpData );
2607     IDirectPlayX_Release( pDP[0] );
2608     IDirectPlayX_Release( pDP[1] );
2609
2610 }
2611
2612 /* GetPlayerAccount */
2613
2614 static BOOL CALLBACK EnumSessions_cb_join_secure( LPCDPSESSIONDESC2 lpThisSD,
2615                                                   LPDWORD lpdwTimeOut,
2616                                                   DWORD dwFlags,
2617                                                   LPVOID lpContext )
2618 {
2619     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
2620     DPSESSIONDESC2 dpsd;
2621     DPCREDENTIALS dpCredentials;
2622     HRESULT hr;
2623
2624     if (dwFlags & DPESC_TIMEDOUT)
2625     {
2626         return FALSE;
2627     }
2628
2629     checkFlags( DPSESSION_SECURESERVER, lpThisSD->dwFlags, FLAGS_DPSESSION );
2630
2631     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2632     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2633     dpsd.guidApplication = appGuid;
2634     dpsd.guidInstance = lpThisSD->guidInstance;
2635
2636     ZeroMemory( &dpCredentials, sizeof(DPCREDENTIALS) );
2637     dpCredentials.dwSize = sizeof(DPCREDENTIALS);
2638     U1(dpCredentials).lpszUsernameA = (LPSTR) "user";
2639     U2(dpCredentials).lpszPasswordA = (LPSTR) "pass";
2640     hr = IDirectPlayX_SecureOpen( pDP, &dpsd, DPOPEN_JOIN,
2641                                   NULL, &dpCredentials );
2642     checkHR( DPERR_LOGONDENIED, hr ); /* TODO: Make this work */
2643
2644     return TRUE;
2645 }
2646
2647 static void test_GetPlayerAccount(void)
2648 {
2649
2650     LPDIRECTPLAY4 pDP[2];
2651     DPSESSIONDESC2 dpsd;
2652     DPID dpid[2];
2653     HRESULT hr;
2654     UINT i;
2655
2656     DWORD dwDataSize = 1024;
2657     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2658
2659
2660     for (i=0; i<2; i++)
2661     {
2662         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2663                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2664     }
2665     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2666     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2667     dpsd.guidApplication = appGuid;
2668     dpsd.dwMaxPlayers = 10;
2669
2670     /* Uninitialized service provider */
2671     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0, lpData, &dwDataSize );
2672     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2673
2674     if ( hr == DP_OK )
2675     {
2676         todo_wine win_skip( "GetPlayerAccount not implemented\n" );
2677         return;
2678     }
2679
2680
2681     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2682     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2683
2684
2685     /* No session */
2686     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0, lpData, &dwDataSize );
2687     checkHR( DPERR_NOSESSIONS, hr );
2688
2689
2690     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2691     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2692                                pDP[1], 0 );
2693
2694     for (i=0; i<2; i++)
2695     {
2696         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL,
2697                                         0, 0 );
2698         checkHR( DP_OK, hr );
2699     }
2700
2701
2702     /* Session is not secure */
2703     dwDataSize = 1024;
2704     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2705                                         lpData, &dwDataSize );
2706     checkHR( DPERR_UNSUPPORTED, hr );
2707     check( 1024, dwDataSize );
2708
2709
2710     /* Open a secure session */
2711     for (i=0; i<2; i++)
2712     {
2713         hr = IDirectPlayX_Close( pDP[i] );
2714         checkHR( DP_OK, hr );
2715     }
2716
2717     dpsd.dwFlags = DPSESSION_SECURESERVER;
2718     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
2719     checkHR( DP_OK, hr );
2720
2721     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
2722                                     NULL, NULL, NULL, 0, 0 );
2723     checkHR( DP_OK, hr );
2724
2725     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0,
2726                                     EnumSessions_cb_join_secure, pDP[1], 0 );
2727     checkHR( DP_OK, hr );
2728
2729     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
2730                                     NULL, NULL, NULL, 0, 0 );
2731     checkHR( DPERR_INVALIDPARAMS, hr );
2732
2733     /* TODO: Player creation so that this works */
2734
2735     /* Invalid player */
2736     dwDataSize = 1024;
2737     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0,
2738                                         lpData, &dwDataSize );
2739     checkHR( DPERR_INVALIDPLAYER, hr );
2740     check( 1024, dwDataSize );
2741
2742     /* Invalid flags */
2743     dwDataSize = 1024;
2744     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], -1,
2745                                         lpData, &dwDataSize );
2746     checkHR( DPERR_INVALIDFLAGS, hr );
2747     check( 1024, dwDataSize );
2748
2749     dwDataSize = 1024;
2750     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 1,
2751                                         lpData, &dwDataSize );
2752     checkHR( DPERR_INVALIDFLAGS, hr );
2753     check( 1024, dwDataSize );
2754
2755     /* Small buffer */
2756     dwDataSize = 1024;
2757     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2758                                         NULL, &dwDataSize );
2759     checkHR( DPERR_INVALIDPLAYER, hr );
2760     check( 0, dwDataSize );
2761
2762     dwDataSize = 0;
2763     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2764                                         lpData, &dwDataSize );
2765     checkHR( DPERR_INVALIDPLAYER, hr );
2766     check( 0, dwDataSize );
2767
2768     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2769                                         lpData, &dwDataSize );
2770     checkHR( DPERR_INVALIDPLAYER, hr );
2771     check( 0, dwDataSize );
2772
2773     /* Normal operation */
2774     dwDataSize = 1024;
2775     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2776                                         lpData, &dwDataSize );
2777     checkHR( DPERR_INVALIDPLAYER, hr );
2778     check( 1024, dwDataSize );
2779
2780
2781     HeapFree( GetProcessHeap(), 0, lpData );
2782     IDirectPlayX_Release( pDP[0] );
2783     IDirectPlayX_Release( pDP[1] );
2784
2785 }
2786
2787 /* GetPlayerAddress */
2788
2789 static BOOL CALLBACK EnumAddress_cb( REFGUID guidDataType,
2790                                      DWORD dwDataSize,
2791                                      LPCVOID lpData,
2792                                      LPVOID lpContext )
2793 {
2794     lpCallbackData callbackData = (lpCallbackData) lpContext;
2795     static REFGUID types[] = { &DPAID_TotalSize,
2796                                &DPAID_ServiceProvider,
2797                                &DPAID_INet,
2798                                &DPAID_INetW };
2799     static DWORD sizes[] = { 4, 16, 12, 24, 4, 16, 10, 20 };
2800
2801
2802     checkGuid( types[callbackData->dwCounter1%4], guidDataType );
2803     check( sizes[callbackData->dwCounter1], dwDataSize );
2804
2805     switch(callbackData->dwCounter1)
2806     {
2807     case 0:
2808         check( 136, *(LPDWORD) lpData );
2809         break;
2810     case 4:
2811         check( 130, *(LPDWORD) lpData );
2812         break;
2813     case 1:
2814     case 5:
2815         checkGuid( &DPSPGUID_TCPIP, lpData );
2816         break;
2817     case 6:
2818         checkStr( "127.0.0.1", (LPSTR) lpData );
2819         break;
2820     default: break;
2821     }
2822
2823
2824     callbackData->dwCounter1++;
2825
2826     return TRUE;
2827 }
2828
2829 static void test_GetPlayerAddress(void)
2830 {
2831
2832     LPDIRECTPLAY4 pDP[2];
2833     LPDIRECTPLAYLOBBY3 pDPL;
2834     DPSESSIONDESC2 dpsd;
2835     DPID dpid[2];
2836     CallbackData callbackData;
2837     HRESULT hr;
2838     UINT i;
2839
2840     DWORD dwDataSize = 1024;
2841     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2842
2843
2844     for (i=0; i<2; i++)
2845     {
2846         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2847                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2848     }
2849     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2850     CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
2851                       &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
2852
2853
2854     /* Uninitialized service provider */
2855     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0, lpData, &dwDataSize );
2856     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2857
2858     if ( hr == DP_OK )
2859     {
2860         todo_wine win_skip( "GetPlayerAddress not implemented\n" );
2861         return;
2862     }
2863
2864     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2865     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2866
2867
2868     /* No session */
2869     dwDataSize = 1024;
2870     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0, lpData, &dwDataSize );
2871     checkHR( DPERR_UNSUPPORTED, hr );
2872     check( 1024, dwDataSize );
2873
2874     dwDataSize = 1024;
2875     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 1, lpData, &dwDataSize );
2876     checkHR( DPERR_INVALIDPLAYER, hr );
2877     check( 1024, dwDataSize );
2878
2879
2880     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2881     dpsd.guidApplication = appGuid;
2882     dpsd.dwMaxPlayers = 10;
2883     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2884     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2885                                pDP[1], 0 );
2886
2887     for (i=0; i<2; i++)
2888     {
2889         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL,
2890                                         0, 0 );
2891         checkHR( DP_OK, hr );
2892     }
2893
2894     /* Invalid player */
2895     dwDataSize = 1024;
2896     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0,
2897                                         lpData, &dwDataSize );
2898     checkHR( DPERR_UNSUPPORTED, hr );
2899     check( 1024, dwDataSize );
2900
2901     dwDataSize = 1024;
2902     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 1,
2903                                         lpData, &dwDataSize );
2904     checkHR( DPERR_INVALIDPLAYER, hr );
2905     check( 1024, dwDataSize );
2906
2907     /* Small buffer */
2908     dwDataSize = 1024;
2909     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2910                                         NULL, &dwDataSize );
2911     checkHR( DPERR_BUFFERTOOSMALL, hr );
2912     check( 136, dwDataSize );
2913
2914     dwDataSize = 0;
2915     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2916                                         lpData, &dwDataSize );
2917     checkHR( DPERR_BUFFERTOOSMALL, hr );
2918     check( 136, dwDataSize );
2919
2920     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2921                                         lpData, &dwDataSize );
2922     checkHR( DP_OK, hr );
2923     check( 136, dwDataSize );
2924
2925
2926     /* Regular parameters */
2927     callbackData.dwCounter1 = 0;
2928
2929     /* - Local */
2930     dwDataSize = 1024;
2931     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2932                                         lpData, &dwDataSize );
2933     checkHR( DP_OK, hr );
2934     check( 136, dwDataSize );
2935
2936     hr = IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb, lpData, dwDataSize,
2937                                        &callbackData );
2938     checkHR( DP_OK, hr );
2939
2940     check( 4, callbackData.dwCounter1 );
2941
2942     /* - Remote */
2943     dwDataSize = 1024;
2944     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[1],
2945                                         lpData, &dwDataSize );
2946     checkHR( DP_OK, hr );
2947     check( 130, dwDataSize );
2948
2949     hr = IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb, lpData, dwDataSize,
2950                                        &callbackData );
2951     checkHR( DP_OK, hr );
2952
2953     check( 8, callbackData.dwCounter1 );
2954
2955
2956     HeapFree( GetProcessHeap(), 0, lpData );
2957     IDirectPlayX_Release( pDP[0] );
2958     IDirectPlayX_Release( pDP[1] );
2959
2960 }
2961
2962 /* GetPlayerFlags */
2963
2964 static void test_GetPlayerFlags(void)
2965 {
2966
2967     LPDIRECTPLAY4 pDP[2];
2968     DPSESSIONDESC2 dpsd;
2969     DPID dpid[4];
2970     HRESULT hr;
2971     UINT i;
2972
2973     DWORD dwFlags = 0;
2974
2975
2976     for (i=0; i<2; i++)
2977     {
2978         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2979                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2980     }
2981     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2982     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2983     dpsd.guidApplication = appGuid;
2984     dpsd.dwMaxPlayers = 10;
2985
2986     /* Uninitialized service provider */
2987     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
2988     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2989
2990     if ( hr == DP_OK )
2991     {
2992         todo_wine win_skip( "GetPlayerFlags not implemented\n" );
2993         return;
2994     }
2995
2996     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2997     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2998
2999
3000     /* No session */
3001     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
3002     checkHR( DPERR_INVALIDPLAYER, hr );
3003
3004     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 1, &dwFlags );
3005     checkHR( DPERR_INVALIDPLAYER, hr );
3006
3007
3008     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
3009     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
3010                                pDP[1], 0 );
3011
3012     for (i=0; i<2; i++)
3013     {
3014         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
3015                                         NULL, NULL, NULL, 0, 0 );
3016         checkHR( DP_OK, hr );
3017     }
3018     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[2],
3019                                     NULL, NULL, NULL,
3020                                     0, DPPLAYER_SPECTATOR );
3021     checkHR( DP_OK, hr );
3022     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[3],
3023                                     NULL, NULL, NULL,
3024                                     0, DPPLAYER_SERVERPLAYER );
3025     checkHR( DP_OK, hr );
3026
3027
3028     /* Invalid player */
3029     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
3030     checkHR( DPERR_INVALIDPLAYER, hr );
3031
3032     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 2, &dwFlags );
3033     checkHR( DPERR_INVALIDPLAYER, hr );
3034
3035     /* Invalid parameters */
3036     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[0], NULL );
3037     checkHR( DPERR_INVALIDPARAMS, hr );
3038
3039
3040     /* Regular parameters */
3041     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[0], &dwFlags );
3042     checkHR( DP_OK, hr );
3043     checkFlags( dwFlags, DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3044
3045     hr = IDirectPlayX_GetPlayerFlags( pDP[1], dpid[1], &dwFlags );
3046     checkHR( DP_OK, hr );
3047     checkFlags( dwFlags, DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3048
3049     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[1], &dwFlags );
3050     checkHR( DP_OK, hr );
3051     checkFlags( dwFlags, 0, FLAGS_DPPLAYER );
3052
3053     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[2], &dwFlags );
3054     checkHR( DP_OK, hr );
3055     checkFlags( dwFlags, DPPLAYER_SPECTATOR | DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3056
3057     hr = IDirectPlayX_GetPlayerFlags( pDP[1], dpid[3], &dwFlags );
3058     checkHR( DP_OK, hr );
3059     checkFlags( dwFlags, DPPLAYER_SERVERPLAYER, FLAGS_DPPLAYER );
3060
3061
3062     IDirectPlayX_Release( pDP[0] );
3063     IDirectPlayX_Release( pDP[1] );
3064
3065 }
3066
3067 /* CreateGroup
3068    CreateGroupInGroup */
3069
3070 static void test_CreateGroup(void)
3071 {
3072
3073     LPDIRECTPLAY4 pDP;
3074     DPSESSIONDESC2 dpsd;
3075     DPID idFrom, idTo, dpid, idGroup, idGroupParent;
3076     DPNAME groupName;
3077     HRESULT hr;
3078     UINT i;
3079
3080     LPCSTR lpData = "data";
3081     DWORD dwDataSize = strlen(lpData)+1;
3082     LPDPMSG_CREATEPLAYERORGROUP lpDataGet = HeapAlloc( GetProcessHeap(),
3083                                                        HEAP_ZERO_MEMORY,
3084                                                        1024 );
3085     DWORD dwDataSizeGet = 1024;
3086     CallbackData callbackData;
3087
3088
3089     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3090                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
3091     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
3092     dpsd.dwSize = sizeof(DPSESSIONDESC2);
3093     dpsd.guidApplication = appGuid;
3094     dpsd.dwMaxPlayers = 10;
3095     ZeroMemory( &groupName, sizeof(DPNAME) );
3096
3097
3098     /* No service provider */
3099     hr = IDirectPlayX_CreateGroup( pDP, &idGroup, NULL, NULL, 0, 0 );
3100     checkHR( DPERR_UNINITIALIZED, hr );
3101
3102     hr = IDirectPlayX_CreateGroupInGroup( pDP, 0, &idGroup, NULL, NULL, 0, 0 );
3103     checkHR( DPERR_UNINITIALIZED, hr );
3104
3105
3106
3107     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
3108
3109
3110     /* No session */
3111     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3112                                    NULL, NULL, 0, 0 );
3113     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
3114
3115     if ( hr == DPERR_UNINITIALIZED )
3116     {
3117         todo_wine win_skip( "CreateGroup not implemented\n" );
3118         return;
3119     }
3120
3121     hr = IDirectPlayX_CreateGroupInGroup( pDP, 0, &idGroup,
3122                                           NULL, NULL, 0, 0 );
3123     checkHR( DPERR_INVALIDGROUP, hr );
3124
3125     hr = IDirectPlayX_CreateGroupInGroup( pDP, 2, &idGroup,
3126                                           NULL, NULL, 0, 0 );
3127     checkHR( DPERR_INVALIDGROUP, hr );
3128
3129
3130     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3131     checkHR( DP_OK, hr );
3132     IDirectPlayX_CreatePlayer( pDP, &dpid,
3133                                NULL, NULL, NULL, 0, 0 );
3134
3135
3136
3137     /* With name */
3138     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3139                                    NULL, NULL, 0, 0 );
3140     checkHR( DP_OK, hr );
3141
3142     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3143                                           NULL, NULL, 0, 0 );
3144     checkHR( DP_OK, hr );
3145
3146     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3147                                    &groupName, NULL, 0, 0 );
3148     checkHR( DP_OK, hr );
3149
3150     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3151                                           &groupName, NULL, 0, 0 );
3152     checkHR( DP_OK, hr );
3153
3154
3155     groupName.dwSize = sizeof(DPNAME);
3156     U1(groupName).lpszShortNameA = (LPSTR) lpData;
3157
3158
3159     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3160                                    &groupName, NULL, 0, 0 );
3161     checkHR( DP_OK, hr );
3162
3163     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3164                                           &groupName, NULL, 0, 0 );
3165     checkHR( DP_OK, hr );
3166
3167
3168     /* Message checking */
3169     for (i=0; i<6; i++)
3170     {
3171         dwDataSizeGet = 1024;
3172         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3173                                    &dwDataSizeGet );
3174         checkHR( DP_OK, hr );
3175         if ( NULL == U1(lpDataGet->dpnName).lpszShortNameA )
3176         {
3177             check( 48, dwDataSizeGet );
3178         }
3179         else
3180         {
3181             check( 48 + dwDataSize, dwDataSizeGet );
3182             checkStr( lpData, U1(lpDataGet->dpnName).lpszShortNameA );
3183         }
3184         check( DPID_SYSMSG, idFrom );
3185         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3186         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3187         checkFlags( DPGROUP_LOCAL,            lpDataGet->dwFlags, FLAGS_DPGROUP );
3188     }
3189     check_messages( pDP, &dpid, 1, &callbackData );
3190     checkStr( "", callbackData.szTrace1 );
3191
3192
3193     /* With data */
3194     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3195                                    NULL, (LPVOID) lpData, -1, 0 );
3196     checkHR( DPERR_INVALIDPARAMS, hr );
3197
3198     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3199                                    NULL, (LPVOID) lpData, 0, 0 );
3200     checkHR( DP_OK, hr );
3201
3202     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3203                                    NULL, NULL, dwDataSize, 0 );
3204     checkHR( DPERR_INVALIDPARAMS, hr );
3205
3206     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3207                                    NULL, (LPVOID) lpData, dwDataSize, 0 );
3208     checkHR( DP_OK, hr );
3209
3210
3211     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3212                                           NULL, (LPVOID) lpData, -1, 0 );
3213     checkHR( DPERR_INVALIDPARAMS, hr );
3214
3215     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3216                                           NULL, (LPVOID) lpData, 0, 0 );
3217     checkHR( DP_OK, hr );
3218
3219     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3220                                           NULL, NULL, dwDataSize, 0 );
3221     checkHR( DPERR_INVALIDPARAMS, hr );
3222
3223     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3224                                           NULL, (LPVOID)lpData, dwDataSize, 0 );
3225     checkHR( DP_OK, hr );
3226
3227
3228     hr = IDirectPlayX_CreateGroup( pDP, &idGroupParent,
3229                                    NULL, NULL, 0, 0 );
3230     checkHR( DP_OK, hr );
3231
3232
3233     /* Message checking */
3234     for (i=0; i<5; i++)
3235     {
3236         dwDataSizeGet = 1024;
3237         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3238                                    &dwDataSizeGet );
3239         checkHR( DP_OK, hr );
3240         check( 48 + lpDataGet->dwDataSize, dwDataSizeGet );
3241         check( DPID_SYSMSG, idFrom );
3242         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3243         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3244         checkFlags( DPGROUP_LOCAL,            lpDataGet->dwFlags, FLAGS_DPGROUP );
3245     }
3246     check_messages( pDP, &dpid, 1, &callbackData );
3247     checkStr( "", callbackData.szTrace1 );
3248
3249
3250     /* Flags and idGroupParent */
3251     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3252                                    NULL, NULL, 0, 0 );
3253     checkHR( DP_OK, hr );
3254
3255     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3256                                    NULL, NULL, 0, DPGROUP_HIDDEN );
3257     checkHR( DP_OK, hr );
3258
3259     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3260                                    NULL, NULL, 0, DPGROUP_STAGINGAREA );
3261     checkHR( DP_OK, hr );
3262
3263     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3264                                    NULL, NULL, 0,
3265                                    DPGROUP_HIDDEN | DPGROUP_STAGINGAREA );
3266     checkHR( DP_OK, hr );
3267
3268
3269     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3270                                           NULL, NULL, 0, 0 );
3271     checkHR( DP_OK, hr );
3272
3273     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3274                                           NULL, NULL, 0, DPGROUP_HIDDEN );
3275     checkHR( DP_OK, hr );
3276
3277     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3278                                           NULL, NULL, 0, DPGROUP_STAGINGAREA );
3279     checkHR( DP_OK, hr );
3280
3281     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3282                                           NULL, NULL, 0,
3283                                           DPGROUP_HIDDEN |
3284                                           DPGROUP_STAGINGAREA );
3285     checkHR( DP_OK, hr );
3286
3287
3288     /* Message checking */
3289     for (i=0; i<8; i++)
3290     {
3291         dwDataSizeGet = 1024;
3292         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3293                                    &dwDataSizeGet );
3294         checkHR( DP_OK, hr );
3295         check( 48, dwDataSizeGet );
3296         check( DPID_SYSMSG, idFrom );
3297         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3298         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3299
3300         if ( lpDataGet->dpIdParent != 0 )
3301         {
3302             check( idGroupParent, lpDataGet->dpIdParent );
3303         }
3304
3305         switch (i%4)
3306         {
3307         case 0:
3308             checkFlags( DPGROUP_LOCAL,
3309                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3310             break;
3311         case 1:
3312             checkFlags( DPGROUP_LOCAL | DPGROUP_HIDDEN,
3313                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3314             break;
3315         case 2:
3316             checkFlags( DPGROUP_STAGINGAREA | DPGROUP_LOCAL,
3317                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3318             break;
3319         case 3:
3320             checkFlags( DPGROUP_STAGINGAREA | DPGROUP_LOCAL | DPGROUP_HIDDEN,
3321                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3322             break;
3323         default: break;
3324         }
3325     }
3326     check_messages( pDP, &dpid, 1, &callbackData );
3327     checkStr( "", callbackData.szTrace1 );
3328
3329
3330     /* If a group is created in C/S mode, no messages are sent */
3331
3332     /* - Peer 2 peer */
3333     IDirectPlayX_Close( pDP );
3334
3335     dpsd.dwFlags = 0;
3336     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3337     checkHR( DP_OK, hr );
3338     hr = IDirectPlayX_CreatePlayer( pDP, &dpid, NULL, NULL, NULL, 0, 0 );
3339     checkHR( DP_OK, hr );
3340
3341     hr = IDirectPlayX_CreateGroup( pDP, &idGroup, NULL, NULL, 0, 0 );
3342     checkHR( DP_OK, hr );
3343
3344     /* Messages are received */
3345     check_messages( pDP, &dpid, 1, &callbackData );
3346     checkStr( "S0,", callbackData.szTrace1 );
3347
3348
3349     /* - Client/Server */
3350     IDirectPlayX_Close( pDP );
3351
3352     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
3353     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3354     checkHR( DP_OK, hr );
3355     hr = IDirectPlayX_CreatePlayer( pDP, &dpid,
3356                                     NULL, NULL, NULL, 0,
3357                                     DPPLAYER_SERVERPLAYER );
3358     checkHR( DP_OK, hr );
3359
3360     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3361                                    NULL, NULL, 0, 0 );
3362     checkHR( DP_OK, hr );
3363
3364     /* No messages */
3365     check_messages( pDP, &dpid, 1, &callbackData );
3366     checkStr( "S0,", callbackData.szTrace1 ); /* Or at least there
3367                                                  shouldn't be messages... */
3368
3369
3370     HeapFree( GetProcessHeap(), 0, lpDataGet );
3371     IDirectPlayX_Release( pDP );
3372
3373 }
3374
3375 /* GroupOwner */
3376
3377 static void test_GroupOwner(void)
3378 {
3379
3380     LPDIRECTPLAY4 pDP[2];
3381     DPSESSIONDESC2 dpsd;
3382     DPID dpid[2], idGroup, idOwner;
3383     HRESULT hr;
3384     UINT i;
3385
3386
3387     for (i=0; i<2; i++)
3388     {
3389         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3390                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3391     }
3392     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
3393     dpsd.dwSize = sizeof(DPSESSIONDESC2);
3394     dpsd.guidApplication = appGuid;
3395     dpsd.dwMaxPlayers = 10;
3396     idGroup = 0;
3397     idOwner = 0;
3398
3399     /* Service provider not initialized */
3400     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3401     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
3402     check( 0, idOwner );
3403
3404     if ( hr == DP_OK )
3405     {
3406         todo_wine win_skip( "GetGroupOwner not implemented\n" );
3407         return;
3408     }
3409
3410
3411     for (i=0; i<2; i++)
3412         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
3413
3414     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
3415     checkHR( DP_OK, hr );
3416     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
3417                                     pDP[1], 0 );
3418     checkHR( DP_OK, hr );
3419
3420     for (i=0; i<2; i++)
3421     {
3422         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
3423                                         NULL, NULL, NULL, 0, 0 );
3424         checkHR( DP_OK, hr );
3425     }
3426
3427     /* Invalid group */
3428     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3429     checkHR( DPERR_INVALIDGROUP, hr );
3430
3431     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup, NULL, NULL, 0, 0 );
3432     checkHR( DP_OK, hr );
3433
3434     /* Fails, because we need a lobby session */
3435     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3436     checkHR( DPERR_UNSUPPORTED, hr );
3437
3438
3439     /* TODO:
3440      * - Make this work
3441      * - Check migration of the ownership of a group
3442      *   when the owner leaves
3443      */
3444
3445
3446     IDirectPlayX_Release( pDP[0] );
3447     IDirectPlayX_Release( pDP[1] );
3448
3449 }
3450
3451 /* EnumPlayers */
3452
3453 static BOOL CALLBACK EnumPlayers_cb( DPID dpId,
3454                                      DWORD dwPlayerType,
3455                                      LPCDPNAME lpName,
3456                                      DWORD dwFlags,
3457                                      LPVOID lpContext )
3458 {
3459     lpCallbackData callbackData = (lpCallbackData) lpContext;
3460     char playerIndex = dpid2char( callbackData->dpid,
3461                                   callbackData->dpidSize,
3462                                   dpId );
3463
3464
3465     /* Trace to study player ids */
3466     callbackData->szTrace1[ callbackData->dwCounter1 ] = playerIndex;
3467     callbackData->dwCounter1++;
3468     callbackData->szTrace1[ callbackData->dwCounter1 ] = '\0';
3469
3470     /* Trace to study flags received */
3471     strcat( callbackData->szTrace2,
3472             ( dwFlags2str(dwFlags, FLAGS_DPENUMPLAYERS) +
3473               strlen("DPENUMPLAYERS_") ) );
3474     strcat( callbackData->szTrace2, ":" );
3475
3476
3477     if ( playerIndex < '5' )
3478     {
3479         check( DPPLAYERTYPE_PLAYER, dwPlayerType );
3480     }
3481     else
3482     {
3483         check( DPPLAYERTYPE_GROUP, dwPlayerType );
3484     }
3485
3486     return TRUE;
3487
3488 }
3489
3490 static BOOL CALLBACK EnumSessions_cb_EnumPlayers( LPCDPSESSIONDESC2 lpThisSD,
3491                                                   LPDWORD lpdwTimeOut,
3492                                                   DWORD dwFlags,
3493                                                   LPVOID lpContext )
3494 {
3495     lpCallbackData callbackData = (lpCallbackData) lpContext;
3496     HRESULT hr;
3497
3498     if (dwFlags & DPESC_TIMEDOUT)
3499     {
3500         return FALSE;
3501     }
3502
3503     /* guid = NULL */
3504     callbackData->dwCounter1 = 0;
3505     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, NULL, EnumPlayers_cb,
3506                                    &callbackData, 0 );
3507     checkHR( DPERR_NOSESSIONS, hr );
3508     check( 0, callbackData->dwCounter1 );
3509
3510     /* guid = appGuid */
3511     callbackData->dwCounter1 = 0;
3512     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, (LPGUID) &appGuid,
3513                                    EnumPlayers_cb, &callbackData, 0 );
3514     checkHR( DPERR_NOSESSIONS, hr );
3515     check( 0, callbackData->dwCounter1 );
3516
3517     callbackData->dwCounter1 = 0;
3518     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, (LPGUID) &appGuid,
3519                                    EnumPlayers_cb, &callbackData,
3520                                    DPENUMPLAYERS_SESSION );
3521     checkHR( DPERR_NOSESSIONS, hr );
3522     check( 0, callbackData->dwCounter1 );
3523
3524     /* guid = guidInstance */
3525     callbackData->dwCounter1 = 0;
3526     hr = IDirectPlayX_EnumPlayers( callbackData->pDP,
3527                                    (LPGUID) &lpThisSD->guidInstance,
3528                                    EnumPlayers_cb, &callbackData, 0 );
3529     checkHR( DPERR_NOSESSIONS, hr );
3530     check( 0, callbackData->dwCounter1 );
3531
3532     callbackData->dwCounter1 = 0;
3533     hr = IDirectPlayX_EnumPlayers( callbackData->pDP,
3534                                    (LPGUID) &lpThisSD->guidInstance,
3535                                    EnumPlayers_cb, &callbackData,
3536                                    DPENUMPLAYERS_SESSION );
3537     checkHR( DPERR_GENERIC, hr ); /* Why? */
3538     check( 0, callbackData->dwCounter1 );
3539
3540     return TRUE;
3541
3542 }
3543
3544 static void test_EnumPlayers(void)
3545 {
3546     LPDIRECTPLAY4 pDP[3];
3547     DPSESSIONDESC2 dpsd[3];
3548     DPID dpid[5+2]; /* 5 players, 2 groups */
3549     CallbackData callbackData;
3550     HRESULT hr;
3551     UINT i;
3552
3553
3554     for (i=0; i<3; i++)
3555     {
3556         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3557                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3558
3559         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
3560         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
3561     }
3562
3563     dpsd[0].guidApplication = appGuid;
3564     dpsd[1].guidApplication = appGuid2;
3565     dpsd[2].guidApplication = GUID_NULL;
3566
3567     callbackData.dpid = dpid;
3568     callbackData.dpidSize = 5+2;
3569
3570
3571     /* Uninitialized service provider */
3572     callbackData.dwCounter1 = 0;
3573     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, NULL,
3574                                    &callbackData, 0 );
3575     checkHR( DPERR_UNINITIALIZED, hr );
3576     check( 0, callbackData.dwCounter1 );
3577
3578
3579     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
3580     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
3581     init_TCPIP_provider( pDP[2], "127.0.0.1", 0 );
3582
3583
3584     /* No session */
3585     callbackData.dwCounter1 = 0;
3586     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3587                                    &callbackData, 0 );
3588     todo_wine checkHR( DPERR_NOSESSIONS, hr );
3589     check( 0, callbackData.dwCounter1 );
3590
3591     if ( hr == DPERR_UNINITIALIZED )
3592     {
3593         todo_wine win_skip( "EnumPlayers not implemented\n" );
3594         return;
3595     }
3596
3597     callbackData.dwCounter1 = 0;
3598     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3599                                    &callbackData, 0 );
3600     checkHR( DPERR_NOSESSIONS, hr );
3601     check( 0, callbackData.dwCounter1 );
3602
3603     callbackData.dwCounter1 = 0;
3604     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3605                                    &callbackData, DPENUMPLAYERS_SESSION );
3606     checkHR( DPERR_NOSESSIONS, hr );
3607     check( 0, callbackData.dwCounter1 );
3608
3609
3610     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
3611     checkHR( DP_OK, hr );
3612     hr = IDirectPlayX_Open( pDP[1], &dpsd[1], DPOPEN_CREATE );
3613     checkHR( DP_OK, hr );
3614
3615
3616     /* No players */
3617     callbackData.dwCounter1 = 0;
3618     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3619                                    &callbackData, 0 );
3620     checkHR( DP_OK, hr );
3621     check( 0, callbackData.dwCounter1 );
3622
3623
3624     /* Create players */
3625     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
3626                                     NULL, NULL, NULL, 0,
3627                                     DPPLAYER_SERVERPLAYER );
3628     checkHR( DP_OK, hr );
3629     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
3630                                     NULL, NULL, NULL, 0,
3631                                     0 );
3632     checkHR( DP_OK, hr );
3633
3634     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[2],
3635                                     NULL, NULL, NULL, 0,
3636                                     0 );
3637     checkHR( DP_OK, hr );
3638     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[5],
3639                                    NULL, NULL, 0, 0 );
3640     checkHR( DP_OK, hr );
3641
3642
3643     /* Invalid parameters */
3644     callbackData.dwCounter1 = 0;
3645     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, NULL,
3646                                    &callbackData, 0 );
3647     checkHR( DPERR_INVALIDPARAMS, hr );
3648     check( 0, callbackData.dwCounter1 );
3649
3650     callbackData.dwCounter1 = 0;
3651     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3652                                    &callbackData, DPENUMPLAYERS_SESSION );
3653     checkHR( DPERR_INVALIDPARAMS, hr );
3654     check( 0, callbackData.dwCounter1 );
3655
3656
3657     /* Regular operation */
3658     callbackData.dwCounter1 = 0;
3659     callbackData.szTrace2[0] = 0;
3660     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3661                                    &callbackData, 0 );
3662     checkHR( DP_OK, hr );
3663     check( 2, callbackData.dwCounter1 );
3664     checkStr( "20", callbackData.szTrace1 );
3665     checkStr( "ALL:SERVERPLAYER:", callbackData.szTrace2 );
3666
3667     callbackData.dwCounter1 = 0;
3668     callbackData.szTrace2[0] = 0;
3669     hr = IDirectPlayX_EnumPlayers( pDP[1], NULL, EnumPlayers_cb,
3670                                    &callbackData, 0 );
3671     checkHR( DP_OK, hr );
3672     check( 1, callbackData.dwCounter1 );
3673     checkStr( "1", callbackData.szTrace1 );
3674     checkStr( "ALL:", callbackData.szTrace2 );
3675
3676     callbackData.dwCounter1 = 0;
3677     callbackData.szTrace2[0] = 0;
3678     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3679                                    &callbackData, 0 );
3680     checkHR( DP_OK, hr );
3681     check( 2, callbackData.dwCounter1 ); /* Guid is ignored */
3682     checkStr( "20", callbackData.szTrace1 );
3683     checkStr( "ALL:SERVERPLAYER:", callbackData.szTrace2 );
3684
3685
3686     /* Enumerating from a remote session */
3687     /* - Session not open */
3688     callbackData.pDP = pDP[2];
3689     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[2], 0,
3690                                     EnumSessions_cb_EnumPlayers,
3691                                     &callbackData, 0 );
3692     checkHR( DP_OK, hr );
3693
3694
3695     /* - Open session */
3696     callbackData.pDP = pDP[2];
3697     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[0], 0, EnumSessions_cb_join,
3698                                     pDP[2], 0 );
3699     checkHR( DP_OK, hr );
3700     hr = IDirectPlayX_CreatePlayer( pDP[2], &dpid[3],
3701                                     NULL, NULL, NULL, 0,
3702                                     DPPLAYER_SPECTATOR );
3703     checkHR( DP_OK, hr );
3704     hr = IDirectPlayX_CreatePlayer( pDP[2], &dpid[4],
3705                                     NULL, NULL, NULL, 0,
3706                                     0 );
3707     checkHR( DP_OK, hr );
3708     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[6],
3709                                    NULL, NULL, 0, 0 );
3710     checkHR( DP_OK, hr );
3711
3712     callbackData.dwCounter1 = 0;
3713     callbackData.szTrace2[0] = 0;
3714     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3715                                    &callbackData, 0 );
3716     checkHR( DP_OK, hr );
3717     check( 4, callbackData.dwCounter1 );
3718     checkStr( "4302", callbackData.szTrace1 );
3719     checkStr( "ALL:SPECTATOR:SERVERPLAYER:ALL:", callbackData.szTrace2 );
3720
3721
3722     /* Flag tests */
3723
3724     callbackData.dwCounter1 = 0;
3725     callbackData.szTrace2[0] = 0;
3726     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3727                                    &callbackData, DPENUMPLAYERS_ALL );
3728     checkHR( DP_OK, hr );
3729     check( 4, callbackData.dwCounter1 );
3730     checkStr( "4302", callbackData.szTrace1 );
3731     checkStr( "ALL:SPECTATOR:SERVERPLAYER:ALL:", callbackData.szTrace2 );
3732
3733     callbackData.dwCounter1 = 0;
3734     callbackData.szTrace2[0] = 0;
3735     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3736                                    &callbackData, DPENUMPLAYERS_GROUP );
3737     checkHR( DP_OK, hr );
3738     check( 6, callbackData.dwCounter1 );
3739     checkStr( "430256", callbackData.szTrace1 );
3740     checkStr( "GROUP:"
3741               "GROUP,DPENUMPLAYERS_SPECTATOR:"
3742               "GROUP,DPENUMPLAYERS_SERVERPLAYER:"
3743               "GROUP:ALL:ALL:", callbackData.szTrace2 );
3744
3745     callbackData.dwCounter1 = 0;
3746     callbackData.szTrace2[0] = 0;
3747     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3748                                    &callbackData, DPENUMPLAYERS_LOCAL );
3749     checkHR( DP_OK, hr );
3750     check( 2, callbackData.dwCounter1 );
3751     checkStr( "43", callbackData.szTrace1 );
3752     checkStr( "LOCAL:"
3753               "LOCAL,DPENUMPLAYERS_SPECTATOR:", callbackData.szTrace2 );
3754
3755     callbackData.dwCounter1 = 0;
3756     callbackData.szTrace2[0] = 0;
3757     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3758                                    &callbackData, DPENUMPLAYERS_SERVERPLAYER );
3759     checkHR( DP_OK, hr );
3760     check( 1, callbackData.dwCounter1 );
3761     checkStr( "0", callbackData.szTrace1 );
3762     checkStr( "SERVERPLAYER:", callbackData.szTrace2 );
3763
3764     callbackData.dwCounter1 = 0;
3765     callbackData.szTrace2[0] = 0;
3766     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3767                                    &callbackData, DPENUMPLAYERS_SPECTATOR );
3768     checkHR( DP_OK, hr );
3769     check( 1, callbackData.dwCounter1 );
3770     checkStr( "3", callbackData.szTrace1 );
3771     checkStr( "SPECTATOR:", callbackData.szTrace2 );
3772
3773
3774     IDirectPlayX_Release( pDP[0] );
3775     IDirectPlayX_Release( pDP[1] );
3776     IDirectPlayX_Release( pDP[2] );
3777
3778 }
3779
3780 /* EnumGroups */
3781
3782 static BOOL CALLBACK EnumGroups_cb( DPID dpId,
3783                                     DWORD dwPlayerType,
3784                                     LPCDPNAME lpName,
3785                                     DWORD dwFlags,
3786                                     LPVOID lpContext )
3787 {
3788     lpCallbackData callbackData = (lpCallbackData) lpContext;
3789     char playerIndex = dpid2char( callbackData->dpid,
3790                                   callbackData->dpidSize,
3791                                   dpId );
3792
3793
3794     /* Trace to study player ids */
3795     callbackData->szTrace1[ callbackData->dwCounter1 ] = playerIndex;
3796     callbackData->dwCounter1++;
3797     callbackData->szTrace1[ callbackData->dwCounter1 ] = '\0';
3798
3799     /* Trace to study flags received */
3800     strcat( callbackData->szTrace2,
3801             ( dwFlags2str(dwFlags, FLAGS_DPENUMGROUPS) +
3802               strlen("DPENUMGROUPS_") ) );
3803     strcat( callbackData->szTrace2, ":" );
3804
3805
3806     check( DPPLAYERTYPE_GROUP, dwPlayerType );
3807
3808     return TRUE;
3809 }
3810
3811 static BOOL CALLBACK EnumSessions_cb_EnumGroups( LPCDPSESSIONDESC2 lpThisSD,
3812                                                  LPDWORD lpdwTimeOut,
3813                                                  DWORD dwFlags,
3814                                                  LPVOID lpContext )
3815 {
3816     lpCallbackData callbackData = (lpCallbackData) lpContext;
3817     HRESULT hr;
3818
3819     if (dwFlags & DPESC_TIMEDOUT)
3820     {
3821         return FALSE;
3822     }
3823
3824     /* guid = NULL */
3825     callbackData->dwCounter1 = 0;
3826     hr = IDirectPlayX_EnumGroups( callbackData->pDP, NULL,
3827                                   EnumGroups_cb, &callbackData, 0 );
3828     checkHR( DPERR_NOSESSIONS, hr );
3829     check( 0, callbackData->dwCounter1 );
3830
3831     /* guid = appGuid */
3832     callbackData->dwCounter1 = 0;
3833     hr = IDirectPlayX_EnumGroups( callbackData->pDP, (LPGUID) &appGuid,
3834                                   EnumGroups_cb, &callbackData, 0 );
3835     checkHR( DPERR_NOSESSIONS, hr );
3836     check( 0, callbackData->dwCounter1 );
3837
3838     callbackData->dwCounter1 = 0;
3839     hr = IDirectPlayX_EnumGroups( callbackData->pDP, (LPGUID) &appGuid,
3840                                   EnumGroups_cb, &callbackData,
3841                                   DPENUMGROUPS_SESSION );
3842     checkHR( DPERR_NOSESSIONS, hr );
3843     check( 0, callbackData->dwCounter1 );
3844
3845     /* guid = guidInstance */
3846     callbackData->dwCounter1 = 0;
3847     hr = IDirectPlayX_EnumGroups( callbackData->pDP,
3848                                   (LPGUID) &lpThisSD->guidInstance,
3849                                   EnumGroups_cb, &callbackData, 0 );
3850     checkHR( DPERR_NOSESSIONS, hr );
3851     check( 0, callbackData->dwCounter1 );
3852
3853     callbackData->dwCounter1 = 0;
3854     hr = IDirectPlayX_EnumGroups( callbackData->pDP,
3855                                   (LPGUID) &lpThisSD->guidInstance,
3856                                   EnumGroups_cb, &callbackData,
3857                                   DPENUMGROUPS_SESSION );
3858     checkHR( DPERR_GENERIC, hr ); /* Why? */
3859     check( 0, callbackData->dwCounter1 );
3860
3861     return TRUE;
3862
3863 }
3864
3865 static void test_EnumGroups(void)
3866 {
3867     LPDIRECTPLAY4 pDP[3];
3868     DPSESSIONDESC2 dpsd[3];
3869     DPID dpid[5];
3870     CallbackData callbackData;
3871     HRESULT hr;
3872     UINT i;
3873
3874
3875     for (i=0; i<3; i++)
3876     {
3877         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3878                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3879
3880         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
3881         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
3882     }
3883
3884     dpsd[0].guidApplication = appGuid;
3885     dpsd[1].guidApplication = appGuid2;
3886     dpsd[2].guidApplication = GUID_NULL;
3887
3888     callbackData.dpid = dpid;
3889     callbackData.dpidSize = 5;
3890
3891
3892     /* Uninitialized service provider */
3893     callbackData.dwCounter1 = 0;
3894     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3895                                   &callbackData, 0 );
3896     checkHR( DPERR_UNINITIALIZED, hr );
3897     check( 0, callbackData.dwCounter1 );
3898
3899
3900     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
3901     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
3902     init_TCPIP_provider( pDP[2], "127.0.0.1", 0 );
3903
3904
3905     /* No session */
3906     callbackData.dwCounter1 = 0;
3907     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3908                                   &callbackData, 0 );
3909     todo_wine checkHR( DPERR_NOSESSIONS, hr );
3910     check( 0, callbackData.dwCounter1 );
3911
3912     if ( hr == DPERR_UNINITIALIZED )
3913     {
3914         todo_wine win_skip( "EnumGroups not implemented\n" );
3915         return;
3916     }
3917
3918     callbackData.dwCounter1 = 0;
3919     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, EnumGroups_cb,
3920                                   &callbackData, 0 );
3921     checkHR( DPERR_NOSESSIONS, hr );
3922     check( 0, callbackData.dwCounter1 );
3923
3924     callbackData.dwCounter1 = 0;
3925     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, EnumGroups_cb,
3926                                   &callbackData, DPENUMGROUPS_SESSION );
3927     checkHR( DPERR_NOSESSIONS, hr );
3928     check( 0, callbackData.dwCounter1 );
3929
3930
3931     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
3932     checkHR( DP_OK, hr );
3933     hr = IDirectPlayX_Open( pDP[1], &dpsd[1], DPOPEN_CREATE );
3934     checkHR( DP_OK, hr );
3935
3936
3937     /* No groups */
3938     callbackData.dwCounter1 = 0;
3939     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3940                                   &callbackData, 0 );
3941     checkHR( DP_OK, hr );
3942     check( 0, callbackData.dwCounter1 );
3943
3944
3945     /* Create groups */
3946     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[0],
3947                                    NULL, NULL, 0, 0 );
3948     checkHR( DP_OK, hr );
3949     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[0], &dpid[3],
3950                                           NULL, NULL, 0, 0 );
3951     checkHR( DP_OK, hr ); /* Not a superior level group,
3952                              won't appear in the enumerations */
3953     hr = IDirectPlayX_CreateGroup( pDP[1], &dpid[1],
3954                                    NULL, NULL, 0, 0 );
3955     checkHR( DP_OK, hr );
3956     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[2],
3957                                    NULL, NULL, 0, DPGROUP_HIDDEN );
3958     checkHR( DP_OK, hr );
3959
3960
3961     /* Invalid parameters */
3962     callbackData.dwCounter1 = 0;
3963     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, NULL,
3964                                   &callbackData, 0 );
3965     checkHR( DPERR_INVALIDPARAMS, hr );
3966     check( 0, callbackData.dwCounter1 );
3967
3968     callbackData.dwCounter1 = 0;
3969     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3970                                   &callbackData, DPENUMGROUPS_SESSION );
3971     checkHR( DPERR_INVALIDPARAMS, hr );
3972     check( 0, callbackData.dwCounter1 );
3973
3974
3975     /* Regular operation */
3976     callbackData.dwCounter1 = 0;
3977     callbackData.szTrace2[0] = 0;
3978     hr = IDirectPlayX_EnumGroups( pDP[0], NULL, EnumGroups_cb,
3979                                   &callbackData, 0 );
3980     checkHR( DP_OK, hr );
3981     check( 2, callbackData.dwCounter1 );
3982     checkStr( "02", callbackData.szTrace1 );
3983     checkStr( "ALL:HIDDEN:", callbackData.szTrace2 );
3984
3985     callbackData.dwCounter1 = 0;
3986     callbackData.szTrace2[0] = 0;
3987     hr = IDirectPlayX_EnumGroups( pDP[1], NULL, EnumGroups_cb,
3988                                   &callbackData, 0 );
3989     checkHR( DP_OK, hr );
3990     check( 1, callbackData.dwCounter1 );
3991     checkStr( "1", callbackData.szTrace1 );
3992     checkStr( "ALL:", callbackData.szTrace2 );
3993
3994     callbackData.dwCounter1 = 0;
3995     callbackData.szTrace2[0] = 0;
3996     hr = IDirectPlayX_EnumGroups( pDP[0], (LPGUID) &appGuid, EnumGroups_cb,
3997                                   &callbackData, 0 );
3998     checkHR( DP_OK, hr );
3999     check( 2, callbackData.dwCounter1 ); /* Guid is ignored */
4000     checkStr( "02", callbackData.szTrace1 );
4001     checkStr( "ALL:HIDDEN:", callbackData.szTrace2 );
4002
4003
4004     /* Enumerating from a remote session */
4005     /* - Session not open */
4006     callbackData.pDP = pDP[2];
4007     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[2], 0,
4008                                     EnumSessions_cb_EnumGroups,
4009                                     &callbackData, 0 );
4010     checkHR( DP_OK, hr );
4011
4012     /* - Open session */
4013     callbackData.pDP = pDP[2];
4014     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[0], 0, EnumSessions_cb_join,
4015                                     pDP[2], 0 );
4016     checkHR( DP_OK, hr );
4017
4018     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[3],
4019                                    NULL, NULL, 0, 0 );
4020     checkHR( DP_OK, hr );
4021     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[4],
4022                                    NULL, NULL, 0, DPGROUP_STAGINGAREA );
4023     checkHR( DP_OK, hr );
4024
4025
4026     callbackData.dwCounter1 = 0;
4027     callbackData.szTrace2[0] = 0;
4028     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4029                                   &callbackData, 0 );
4030     checkHR( DP_OK, hr );
4031     check( 4, callbackData.dwCounter1 );
4032     checkStr( "0234", callbackData.szTrace1 );
4033     checkStr( "ALL:HIDDEN:ALL:STAGINGAREA:", callbackData.szTrace2 );
4034
4035     /* Flag tests */
4036     callbackData.dwCounter1 = 0;
4037     callbackData.szTrace2[0] = 0;
4038     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4039                                   &callbackData, DPENUMGROUPS_ALL );
4040     checkHR( DP_OK, hr );
4041     check( 4, callbackData.dwCounter1 );
4042     checkStr( "0234", callbackData.szTrace1 );
4043     checkStr( "ALL:HIDDEN:ALL:STAGINGAREA:", callbackData.szTrace2 );
4044
4045     callbackData.dwCounter1 = 0;
4046     callbackData.szTrace2[0] = 0;
4047     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4048                                   &callbackData, DPENUMGROUPS_HIDDEN );
4049     checkHR( DP_OK, hr );
4050     check( 1, callbackData.dwCounter1 );
4051     checkStr( "2", callbackData.szTrace1 );
4052     checkStr( "HIDDEN:", callbackData.szTrace2 );
4053
4054     callbackData.dwCounter1 = 0;
4055     callbackData.szTrace2[0] = 0;
4056     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4057                                   &callbackData, DPENUMGROUPS_LOCAL );
4058     checkHR( DP_OK, hr );
4059     check( 2, callbackData.dwCounter1 );
4060     checkStr( "34", callbackData.szTrace1 );
4061     checkStr( "LOCAL:"
4062               "LOCAL,DPENUMGROUPS_STAGINGAREA:", callbackData.szTrace2 );
4063
4064     callbackData.dwCounter1 = 0;
4065     callbackData.szTrace2[0] = 0;
4066     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4067                                   &callbackData, DPENUMGROUPS_REMOTE );
4068     checkHR( DP_OK, hr );
4069     check( 2, callbackData.dwCounter1 );
4070     checkStr( "02", callbackData.szTrace1 );
4071     checkStr( "REMOTE:"
4072               "REMOTE,DPENUMGROUPS_HIDDEN:", callbackData.szTrace2 );
4073
4074     callbackData.dwCounter1 = 0;
4075     callbackData.szTrace2[0] = 0;
4076     hr = IDirectPlayX_EnumGroups( pDP[2], NULL, EnumGroups_cb,
4077                                   &callbackData, DPENUMGROUPS_STAGINGAREA );
4078     checkHR( DP_OK, hr );
4079     check( 1, callbackData.dwCounter1 );
4080     checkStr( "4", callbackData.szTrace1 );
4081     checkStr( "STAGINGAREA:", callbackData.szTrace2 );
4082
4083
4084     IDirectPlayX_Release( pDP[0] );
4085     IDirectPlayX_Release( pDP[1] );
4086     IDirectPlayX_Release( pDP[2] );
4087
4088 }
4089
4090 static void test_EnumGroupsInGroup(void)
4091 {
4092     LPDIRECTPLAY4 pDP[2];
4093     DPSESSIONDESC2 dpsd[2];
4094     DPID dpid[6];
4095     CallbackData callbackData;
4096     HRESULT hr;
4097     UINT i;
4098
4099
4100     for (i=0; i<2; i++)
4101     {
4102         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4103                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4104
4105         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
4106         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
4107     }
4108
4109     dpsd[0].guidApplication = appGuid;
4110     dpsd[1].guidApplication = GUID_NULL;
4111
4112     callbackData.dpid = dpid;
4113     callbackData.dpidSize = 6;
4114
4115
4116     /* Uninitialized service provider */
4117     callbackData.dwCounter1 = 0;
4118     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], 0, NULL, EnumGroups_cb,
4119                                          &callbackData, 0 );
4120     checkHR( DPERR_UNINITIALIZED, hr );
4121     check( 0, callbackData.dwCounter1 );
4122
4123
4124     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4125     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4126
4127     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
4128     todo_wine checkHR( DP_OK, hr );
4129
4130     if ( hr == DPERR_UNINITIALIZED )
4131     {
4132         todo_wine win_skip( "EnumGroupsInGroup not implemented\n" );
4133         return;
4134     }
4135
4136     /* Create groups */
4137     /*
4138      * 0
4139      *   / 2
4140      * 1 | 3
4141      *   | 4
4142      *   \ 5 (shortcut)
4143      */
4144     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[0],
4145                                    NULL, NULL, 0, 0 );
4146     checkHR( DP_OK, hr );
4147     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[1],
4148                                    NULL, NULL, 0, 0 );
4149     checkHR( DP_OK, hr );
4150     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[1], &dpid[2],
4151                                           NULL, NULL, 0, 0 );
4152     checkHR( DP_OK, hr );
4153     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[1], &dpid[3],
4154                                           NULL, NULL, 0,
4155                                           DPGROUP_HIDDEN );
4156     checkHR( DP_OK, hr );
4157     hr = IDirectPlayX_CreateGroupInGroup( pDP[0], dpid[1], &dpid[4],
4158                                           NULL, NULL, 0,
4159                                           DPGROUP_STAGINGAREA );
4160     checkHR( DP_OK, hr );
4161     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[5],
4162                                    NULL, NULL, 0, 0 );
4163     checkHR( DP_OK, hr );
4164
4165     hr = IDirectPlayX_AddGroupToGroup( pDP[0], dpid[1], dpid[5] );
4166     checkHR( DP_OK, hr );
4167
4168
4169     /* Invalid parameters */
4170     callbackData.dwCounter1 = 0;
4171     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], 0, NULL, EnumGroups_cb,
4172                                          &callbackData, 0 );
4173     checkHR( DPERR_INVALIDGROUP, hr );
4174     check( 0, callbackData.dwCounter1 );
4175
4176     callbackData.dwCounter1 = 0;
4177     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], 10, NULL, EnumGroups_cb,
4178                                          &callbackData, 0 );
4179     checkHR( DPERR_INVALIDGROUP, hr );
4180     check( 0, callbackData.dwCounter1 );
4181
4182     callbackData.dwCounter1 = 0;
4183     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], (LPGUID) &appGuid,
4184                                          NULL, &callbackData, 0 );
4185     checkHR( DPERR_INVALIDPARAMS, hr );
4186     check( 0, callbackData.dwCounter1 );
4187
4188     callbackData.dwCounter1 = 0;
4189     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4190                                          &callbackData, DPENUMGROUPS_SESSION );
4191     checkHR( DPERR_INVALIDPARAMS, hr );
4192     check( 0, callbackData.dwCounter1 );
4193
4194
4195     /* Regular operation */
4196     callbackData.dwCounter1 = 0;
4197     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[0], NULL, EnumGroups_cb,
4198                                          &callbackData, 0 );
4199     checkHR( DP_OK, hr );
4200     check( 0, callbackData.dwCounter1 );
4201
4202     callbackData.dwCounter1 = 0;
4203     callbackData.szTrace2[0] = 0;
4204     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4205                                          &callbackData, 0 );
4206     checkHR( DP_OK, hr );
4207     check( 4, callbackData.dwCounter1 );
4208     checkStr( "5432", callbackData.szTrace1 );
4209     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4210
4211     callbackData.dwCounter1 = 0;
4212     callbackData.szTrace2[0] = 0;
4213     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], (LPGUID) &appGuid,
4214                                          EnumGroups_cb, &callbackData, 0 );
4215     checkHR( DP_OK, hr );
4216     check( 4, callbackData.dwCounter1 ); /* Guid is ignored */
4217     checkStr( "5432", callbackData.szTrace1 );
4218     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4219
4220
4221     /* Enumerating from a remote session */
4222     /* - Session not open */
4223     callbackData.pDP = pDP[1];
4224     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd[1], 0,
4225                                     EnumSessions_cb_EnumGroups,
4226                                     &callbackData, 0 );
4227     checkHR( DP_OK, hr );
4228
4229     /* - Open session */
4230     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd[0], 0, EnumSessions_cb_join,
4231                                     pDP[1], 0 );
4232     checkHR( DP_OK, hr );
4233
4234
4235     callbackData.dwCounter1 = 0;
4236     callbackData.szTrace2[0] = 0;
4237     hr = IDirectPlayX_EnumGroupsInGroup( pDP[1], dpid[1], NULL, EnumGroups_cb,
4238                                          &callbackData, 0 );
4239     checkHR( DP_OK, hr );
4240     check( 4, callbackData.dwCounter1 );
4241     checkStr( "5432", callbackData.szTrace1 );
4242     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4243
4244     /* Flag tests */
4245     callbackData.dwCounter1 = 0;
4246     callbackData.szTrace2[0] = 0;
4247     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4248                                          &callbackData, DPENUMGROUPS_ALL );
4249     checkHR( DP_OK, hr );
4250     check( 4, callbackData.dwCounter1 );
4251     checkStr( "5432", callbackData.szTrace1 );
4252     checkStr( "SHORTCUT:STAGINGAREA:HIDDEN:ALL:", callbackData.szTrace2 );
4253
4254     callbackData.dwCounter1 = 0;
4255     callbackData.szTrace2[0] = 0;
4256     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4257                                          &callbackData, DPENUMGROUPS_HIDDEN );
4258     checkHR( DP_OK, hr );
4259     check( 1, callbackData.dwCounter1 );
4260     checkStr( "3", callbackData.szTrace1 );
4261     checkStr( "HIDDEN:", callbackData.szTrace2 );
4262
4263     callbackData.dwCounter1 = 0;
4264     callbackData.szTrace2[0] = 0;
4265     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4266                                          &callbackData, DPENUMGROUPS_LOCAL );
4267     checkHR( DP_OK, hr );
4268     check( 4, callbackData.dwCounter1 );
4269     checkStr( "5432", callbackData.szTrace1 );
4270     checkStr( "LOCAL,DPENUMGROUPS_SHORTCUT:"
4271               "LOCAL,DPENUMGROUPS_STAGINGAREA:"
4272               "LOCAL,DPENUMGROUPS_HIDDEN:LOCAL:", callbackData.szTrace2 );
4273
4274     callbackData.dwCounter1 = 0;
4275     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4276                                          &callbackData, DPENUMGROUPS_REMOTE );
4277     checkHR( DP_OK, hr );
4278     check( 0, callbackData.dwCounter1 );
4279
4280     callbackData.dwCounter1 = 0;
4281     hr = IDirectPlayX_EnumGroupsInGroup( pDP[1], dpid[1], NULL, EnumGroups_cb,
4282                                          &callbackData, DPENUMGROUPS_LOCAL );
4283     checkHR( DP_OK, hr );
4284     check( 0, callbackData.dwCounter1 );
4285
4286     callbackData.dwCounter1 = 0;
4287     callbackData.szTrace2[0] = 0;
4288     hr = IDirectPlayX_EnumGroupsInGroup( pDP[1], dpid[1], NULL, EnumGroups_cb,
4289                                          &callbackData, DPENUMGROUPS_REMOTE );
4290     checkHR( DP_OK, hr );
4291     check( 4, callbackData.dwCounter1 );
4292     checkStr( "5432", callbackData.szTrace1 );
4293     checkStr( "REMOTE,DPENUMGROUPS_SHORTCUT:"
4294               "REMOTE,DPENUMGROUPS_STAGINGAREA:"
4295               "REMOTE,DPENUMGROUPS_HIDDEN:REMOTE:", callbackData.szTrace2 );
4296
4297     callbackData.dwCounter1 = 0;
4298     callbackData.szTrace2[0] = 0;
4299     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4300                                          &callbackData, DPENUMGROUPS_SHORTCUT );
4301     checkHR( DP_OK, hr );
4302     check( 1, callbackData.dwCounter1 );
4303     checkStr( "5", callbackData.szTrace1 );
4304     checkStr( "SHORTCUT:", callbackData.szTrace2 );
4305
4306     callbackData.dwCounter1 = 0;
4307     callbackData.szTrace2[0] = 0;
4308     hr = IDirectPlayX_EnumGroupsInGroup( pDP[0], dpid[1], NULL, EnumGroups_cb,
4309                                          &callbackData,
4310                                          DPENUMGROUPS_STAGINGAREA );
4311     checkHR( DP_OK, hr );
4312     check( 1, callbackData.dwCounter1 );
4313     checkStr( "4", callbackData.szTrace1 );
4314     checkStr( "STAGINGAREA:", callbackData.szTrace2 );
4315
4316
4317     IDirectPlayX_Release( pDP[0] );
4318     IDirectPlayX_Release( pDP[1] );
4319
4320 }
4321
4322 static void test_groups_p2p(void)
4323 {
4324
4325     LPDIRECTPLAY4 pDP[2];
4326     DPSESSIONDESC2 dpsd;
4327     DPID idPlayer[6], idGroup[3];
4328     HRESULT hr;
4329     UINT i;
4330
4331     DWORD dwDataSize = 1024;
4332     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
4333     CallbackData callbackData;
4334
4335
4336     for (i=0; i<2; i++)
4337     {
4338         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4339                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4340     }
4341     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
4342     dpsd.dwSize = sizeof(DPSESSIONDESC2);
4343     dpsd.guidApplication = appGuid;
4344     dpsd.dwMaxPlayers = 10;
4345
4346
4347     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4348     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4349
4350     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4351     todo_wine checkHR( DP_OK, hr );
4352     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
4353                                     pDP[1], 0 );
4354     todo_wine checkHR( DP_OK, hr );
4355
4356     if ( hr == DPERR_UNINITIALIZED )
4357     {
4358         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
4359         return;
4360     }
4361
4362
4363     /* Create players */
4364     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[0],
4365                                     NULL, NULL, NULL, 0, 0 );
4366     checkHR( DP_OK, hr );
4367     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[1],
4368                                     NULL, NULL, NULL, 0, 0 );
4369     checkHR( DP_OK, hr );
4370     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[2],
4371                                     NULL, NULL, NULL, 0, 0 );
4372     checkHR( DP_OK, hr );
4373     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[3],
4374                                     NULL, NULL, NULL, 0, 0 );
4375     checkHR( DP_OK, hr );
4376     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[4],
4377                                     NULL, NULL, NULL, 0, 0 );
4378     checkHR( DP_OK, hr );
4379     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[5],
4380                                     NULL, NULL, NULL, 0, 0 );
4381     checkHR( DP_OK, hr );
4382
4383     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup[0],
4384                                    NULL, NULL, 0, 0 );
4385     checkHR( DP_OK, hr );
4386     hr = IDirectPlayX_CreateGroup( pDP[1], &idGroup[2],
4387                                    NULL, NULL, 0, 0 );
4388     checkHR( DP_OK, hr );
4389     hr = IDirectPlayX_CreateGroupInGroup( pDP[1], idGroup[2], &idGroup[1],
4390                                           NULL, NULL, 0, 0 );
4391     checkHR( DP_OK, hr );
4392
4393
4394     /* Purge queues */
4395     check_messages( pDP[0], idPlayer, 6, &callbackData );
4396     checkStr( "S0," "S1,S0,"
4397               "S2,S1,S0," "S2,S1,S0,"
4398               "S2,S1,S0," "S2,S1,S0,"
4399               "S2,S1,S0," "S2,S1,S0,", callbackData.szTrace1 );
4400     check_messages( pDP[1], idPlayer, 6, &callbackData );
4401     checkStr( "S3," "S4,S3,"
4402               "S5,S4,S3," "S5,S4,S3,"
4403               "S5,S4,S3,", callbackData.szTrace1 );
4404
4405
4406     /*
4407      * Player 0   |                  |
4408      * Player 1   | Group 0          | pDP 0
4409      * Player 2   |                  |
4410      * Player 3  | Group 1 )          |
4411      * Player 4  |         | Group 2  | pDP 1
4412      * Player 5            |          |
4413      */
4414
4415     /* Build groups */
4416     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[0] );
4417     checkHR( DP_OK, hr );
4418     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[1] );
4419     checkHR( DP_OK, hr );
4420     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[2] );
4421     checkHR( DP_OK, hr );
4422     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[3] );
4423     checkHR( DP_OK, hr );
4424     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[4] );
4425     checkHR( DP_OK, hr );
4426     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[4] );
4427     checkHR( DP_OK, hr );
4428     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[5] );
4429     checkHR( DP_OK, hr );
4430
4431     hr = IDirectPlayX_AddGroupToGroup( pDP[1], idGroup[2], idGroup[1] );
4432     checkHR( DP_OK, hr );
4433
4434     /* Purge queues */
4435     check_messages( pDP[0], idPlayer, 6, &callbackData );
4436     checkStr( "S2,S1,S0," "S2,S1,S0," "S2,S1,S0,"
4437               "S2,S1,S0," "S2,S1,S0," "S2,S1,S0,"
4438               "S2,S1,S0,", callbackData.szTrace1 );
4439     check_messages( pDP[1], idPlayer, 6, &callbackData );
4440     checkStr( "S5,S4,S3," "S5,S4,S3," "S5,S4,S3,"
4441               "S5,S4,S3," "S5,S4,S3," "S5,S4,S3,"
4442               "S5,S4,S3,", callbackData.szTrace1 );
4443
4444
4445     /* Sending broadcast messages, and checking who receives them */
4446
4447     dwDataSize = 4;
4448     /* 0 -> * */
4449     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], DPID_ALLPLAYERS, 0,
4450                             lpData, dwDataSize );
4451     checkHR( DP_OK, hr );
4452     check_messages( pDP[0], idPlayer, 6, &callbackData );
4453     checkStr( "02,01,", callbackData.szTrace1 );
4454     check_messages( pDP[1], idPlayer, 6, &callbackData );
4455     checkStr( "05,04,03,", callbackData.szTrace1 );
4456
4457     /* 0 -> g0 */
4458     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[0], 0,
4459                             lpData, dwDataSize );
4460     checkHR( DP_OK, hr );
4461     check_messages( pDP[0], idPlayer, 6, &callbackData );
4462     checkStr( "02,01,", callbackData.szTrace1 );
4463     check_messages( pDP[1], idPlayer, 6, &callbackData );
4464     checkStr( "", callbackData.szTrace1 );
4465     /* 0 -> g1 */
4466     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[1], 0,
4467                             lpData, dwDataSize );
4468     checkHR( DP_OK, hr );
4469     check_messages( pDP[0], idPlayer, 6, &callbackData );
4470     checkStr( "", callbackData.szTrace1 );
4471     check_messages( pDP[1], idPlayer, 6, &callbackData );
4472     checkStr( "04,03,", callbackData.szTrace1 );
4473     /* 0 -> g2 */
4474     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[2], 0,
4475                             lpData, dwDataSize );
4476     checkHR( DP_OK, hr );
4477     check_messages( pDP[0], idPlayer, 6, &callbackData );
4478     checkStr( "", callbackData.szTrace1 );
4479     check_messages( pDP[1], idPlayer, 6, &callbackData );
4480     checkStr( "05,04,", callbackData.szTrace1 );
4481
4482     /* 3 -> * */
4483     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], DPID_ALLPLAYERS, 0,
4484                             lpData, dwDataSize );
4485     checkHR( DP_OK, hr );
4486     check_messages( pDP[0], idPlayer, 6, &callbackData );
4487     checkStr( "32,31,30,", callbackData.szTrace1 );
4488     check_messages( pDP[1], idPlayer, 6, &callbackData );
4489     checkStr( "35,34,", callbackData.szTrace1 );
4490     /* 3 -> g0 */
4491     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[0], 0,
4492                             lpData, dwDataSize );
4493     checkHR( DP_OK, hr );
4494     check_messages( pDP[0], idPlayer, 6, &callbackData );
4495     checkStr( "32,31,30,", callbackData.szTrace1 );
4496     check_messages( pDP[1], idPlayer, 6, &callbackData );
4497     checkStr( "", callbackData.szTrace1 );
4498     /* 3 -> g1 */
4499     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[1], 0,
4500                             lpData, dwDataSize );
4501     checkHR( DP_OK, hr );
4502     check_messages( pDP[0], idPlayer, 6, &callbackData );
4503     checkStr( "", callbackData.szTrace1 );
4504     check_messages( pDP[1], idPlayer, 6, &callbackData );
4505     checkStr( "34,", callbackData.szTrace1 );
4506     /* 3 -> g2 */
4507     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[2], 0,
4508                             lpData, dwDataSize );
4509     checkHR( DP_OK, hr );
4510     check_messages( pDP[0], idPlayer, 6, &callbackData );
4511     checkStr( "", callbackData.szTrace1 );
4512     check_messages( pDP[1], idPlayer, 6, &callbackData );
4513     checkStr( "35,34,", callbackData.szTrace1 );
4514
4515     /* 5 -> * */
4516     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], DPID_ALLPLAYERS, 0,
4517                             lpData, dwDataSize );
4518     checkHR( DP_OK, hr );
4519     check_messages( pDP[0], idPlayer, 6, &callbackData );
4520     checkStr( "52,51,50,", callbackData.szTrace1 );
4521     check_messages( pDP[1], idPlayer, 6, &callbackData );
4522     checkStr( "54,53,", callbackData.szTrace1 );
4523     /* 5 -> g0 */
4524     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[0], 0,
4525                             lpData, dwDataSize );
4526     checkHR( DP_OK, hr );
4527     check_messages( pDP[0], idPlayer, 6, &callbackData );
4528     checkStr( "52,51,50,", callbackData.szTrace1 );
4529     check_messages( pDP[1], idPlayer, 6, &callbackData );
4530     checkStr( "", callbackData.szTrace1 );
4531     /* 5 -> g1 */
4532     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[1], 0,
4533                             lpData, dwDataSize );
4534     checkHR( DP_OK, hr );
4535     check_messages( pDP[0], idPlayer, 6, &callbackData );
4536     checkStr( "", callbackData.szTrace1 );
4537     check_messages( pDP[1], idPlayer, 6, &callbackData );
4538     checkStr( "54,53,", callbackData.szTrace1 );
4539     /* 5 -> g2 */
4540     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[2], 0,
4541                             lpData, dwDataSize );
4542     checkHR( DP_OK, hr );
4543     check_messages( pDP[0], idPlayer, 6, &callbackData );
4544     checkStr( "", callbackData.szTrace1 );
4545     check_messages( pDP[1], idPlayer, 6, &callbackData );
4546     checkStr( "54,", callbackData.szTrace1 );
4547
4548
4549     HeapFree( GetProcessHeap(), 0, lpData );
4550     IDirectPlayX_Release( pDP[0] );
4551     IDirectPlayX_Release( pDP[1] );
4552
4553 }
4554
4555 static void test_groups_cs(void)
4556 {
4557
4558     LPDIRECTPLAY4 pDP[2];
4559     DPSESSIONDESC2 dpsd;
4560     DPID idPlayer[6], idGroup[3];
4561     CallbackData callbackData;
4562     HRESULT hr;
4563     UINT i;
4564
4565     DWORD dwDataSize = 1024;
4566     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
4567
4568
4569     for (i=0; i<2; i++)
4570     {
4571         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4572                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4573     }
4574     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
4575     dpsd.dwSize = sizeof(DPSESSIONDESC2);
4576     dpsd.guidApplication = appGuid;
4577     dpsd.dwMaxPlayers = 10;
4578
4579
4580     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4581     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4582
4583     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
4584     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4585     todo_wine checkHR( DP_OK, hr );
4586     dpsd.dwFlags = 0;
4587     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
4588                                     pDP[1], 0 );
4589     todo_wine checkHR( DP_OK, hr );
4590
4591     if ( hr == DPERR_UNINITIALIZED )
4592     {
4593         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
4594         return;
4595     }
4596
4597
4598     /* Create players */
4599     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[0],
4600                                     NULL, NULL, NULL, 0, 0 );
4601     checkHR( DPERR_ACCESSDENIED, hr );
4602     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[0],
4603                                     NULL, NULL, NULL, 0,
4604                                     DPPLAYER_SERVERPLAYER );
4605     checkHR( DP_OK, hr );
4606     hr = IDirectPlayX_CreatePlayer( pDP[0], &idPlayer[1],
4607                                     NULL, NULL, NULL, 0, 0 );
4608     checkHR( DPERR_ACCESSDENIED, hr );
4609     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[1],
4610                                     NULL, NULL, NULL, 0, 0 );
4611     checkHR( DP_OK, hr );
4612     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[2],
4613                                     NULL, NULL, NULL, 0, 0 );
4614     checkHR( DP_OK, hr );
4615     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[3],
4616                                     NULL, NULL, NULL, 0, 0 );
4617     checkHR( DP_OK, hr );
4618     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[4],
4619                                     NULL, NULL, NULL, 0, 0 );
4620     checkHR( DP_OK, hr );
4621     hr = IDirectPlayX_CreatePlayer( pDP[1], &idPlayer[5],
4622                                     NULL, NULL, NULL, 0, 0 );
4623     checkHR( DP_OK, hr );
4624
4625     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup[0],
4626                                    NULL, NULL, 0, 0 );
4627     checkHR( DP_OK, hr );
4628     hr = IDirectPlayX_CreateGroup( pDP[1], &idGroup[2],
4629                                    NULL, NULL, 0, 0 );
4630     checkHR( DP_OK, hr );
4631     hr = IDirectPlayX_CreateGroupInGroup( pDP[1], idGroup[2], &idGroup[1],
4632                                           NULL, NULL, 0, 0 );
4633     checkHR( DP_OK, hr );
4634
4635
4636     /* Purge queues */
4637     check_messages( pDP[0], idPlayer, 6, &callbackData );
4638     checkStr( "S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
4639     check_messages( pDP[1], idPlayer, 6, &callbackData );
4640     checkStr( "S1," "S2,S1," "S3,S2,S1," "S4,S3,S2,S1,"
4641               "S5,S4,S3,S2,S1," "S5,S4,S3,S2,S1,", callbackData.szTrace1 );
4642
4643     /*
4644      * Player 0   |                  | pDP 0
4645      * Player 1   | Group 0           |
4646      * Player 2   |                   |
4647      * Player 3  | Group 1 )          |
4648      * Player 4  |         | Group 2  | pDP 1
4649      * Player 5            |          |
4650      */
4651
4652     /* Build groups */
4653     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[0] );
4654     checkHR( DP_OK, hr );
4655     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[1] );
4656     checkHR( DP_OK, hr );
4657     hr = IDirectPlayX_AddPlayerToGroup( pDP[0], idGroup[0], idPlayer[2] );
4658     checkHR( DP_OK, hr );
4659     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[3] );
4660     checkHR( DP_OK, hr );
4661     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[1], idPlayer[4] );
4662     checkHR( DP_OK, hr );
4663     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[4] );
4664     checkHR( DP_OK, hr );
4665     hr = IDirectPlayX_AddPlayerToGroup( pDP[1], idGroup[2], idPlayer[5] );
4666     checkHR( DP_OK, hr );
4667
4668     hr = IDirectPlayX_AddGroupToGroup( pDP[1], idGroup[2], idGroup[1] );
4669     checkHR( DP_OK, hr );
4670
4671     /* Purge queues */
4672     check_messages( pDP[0], idPlayer, 6, &callbackData );
4673     checkStr( "S0,S0,S0,S0,", callbackData.szTrace1 );
4674     check_messages( pDP[1], idPlayer, 6, &callbackData );
4675     checkStr( "S5," "S4,S3,S2,S1," "S5,S4,S3,S2,S1,"
4676               "S5,S4,S3,S2,S1," "S5,S4,S3,S2,S1,", callbackData.szTrace1 );
4677
4678
4679     /* Sending broadcast messages, and checking who receives them */
4680     dwDataSize = 4;
4681     /* 0 -> * */
4682     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], DPID_ALLPLAYERS, 0,
4683                             lpData, dwDataSize );
4684     checkHR( DP_OK, hr );
4685     check_messages( pDP[0], idPlayer, 6, &callbackData );
4686     checkStr( "", callbackData.szTrace1 );
4687     check_messages( pDP[1], idPlayer, 6, &callbackData );
4688     checkStr( "05,04,03,02,01,", callbackData.szTrace1 );
4689
4690     /* 0 -> g0 */
4691     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[0], 0,
4692                             lpData, dwDataSize );
4693     checkHR( DP_OK, hr );
4694     check_messages( pDP[0], idPlayer, 6, &callbackData );
4695     checkStr( "", callbackData.szTrace1 );
4696     check_messages( pDP[1], idPlayer, 6, &callbackData );
4697     checkStr( "02,01,", callbackData.szTrace1 );
4698     /* 0 -> g1 */
4699     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[1], 0,
4700                             lpData, dwDataSize );
4701     checkHR( DPERR_INVALIDPARAMS, hr );
4702     check_messages( pDP[0], idPlayer, 6, &callbackData );
4703     checkStr( "", callbackData.szTrace1 );
4704     check_messages( pDP[1], idPlayer, 6, &callbackData );
4705     checkStr( "", callbackData.szTrace1 );
4706     /* 0 -> g2 */
4707     hr = IDirectPlayX_Send( pDP[0], idPlayer[0], idGroup[2], 0,
4708                             lpData, dwDataSize );
4709     checkHR( DPERR_INVALIDPARAMS, hr );
4710     check_messages( pDP[0], idPlayer, 6, &callbackData );
4711     checkStr( "", callbackData.szTrace1 );
4712     check_messages( pDP[1], idPlayer, 6, &callbackData );
4713     checkStr( "", callbackData.szTrace1 );
4714
4715     /* 3 -> * */
4716     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], DPID_ALLPLAYERS, 0,
4717                             lpData, dwDataSize );
4718     checkHR( DP_OK, hr );
4719     check_messages( pDP[0], idPlayer, 6, &callbackData );
4720     checkStr( "30,", callbackData.szTrace1 );
4721     check_messages( pDP[1], idPlayer, 6, &callbackData );
4722     checkStr( "35,34,32,31,", callbackData.szTrace1 );
4723     /* 3 -> g0 */
4724     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[0], 0,
4725                             lpData, dwDataSize );
4726     checkHR( DPERR_INVALIDPARAMS, hr );
4727     check_messages( pDP[0], idPlayer, 6, &callbackData );
4728     checkStr( "", callbackData.szTrace1 );
4729     check_messages( pDP[1], idPlayer, 6, &callbackData );
4730     checkStr( "", callbackData.szTrace1 );
4731     /* 3 -> g1 */
4732     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[1], 0,
4733                             lpData, dwDataSize );
4734     checkHR( DP_OK, hr );
4735     check_messages( pDP[0], idPlayer, 6, &callbackData );
4736     checkStr( "", callbackData.szTrace1 );
4737     check_messages( pDP[1], idPlayer, 6, &callbackData );
4738     checkStr( "34,", callbackData.szTrace1 );
4739     /* 3 -> g2 */
4740     hr = IDirectPlayX_Send( pDP[1], idPlayer[3], idGroup[2], 0,
4741                             lpData, dwDataSize );
4742     checkHR( DP_OK, hr );
4743     check_messages( pDP[0], idPlayer, 6, &callbackData );
4744     checkStr( "", callbackData.szTrace1 );
4745     check_messages( pDP[1], idPlayer, 6, &callbackData );
4746     checkStr( "35,34,", callbackData.szTrace1 );
4747
4748     /* 5 -> * */
4749     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], DPID_ALLPLAYERS, 0,
4750                             lpData, dwDataSize );
4751     checkHR( DP_OK, hr );
4752     check_messages( pDP[0], idPlayer, 6, &callbackData );
4753     checkStr( "50,", callbackData.szTrace1 );
4754     check_messages( pDP[1], idPlayer, 6, &callbackData );
4755     checkStr( "54,53,52,51,", callbackData.szTrace1 );
4756     /* 5 -> g0 */
4757     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[0], 0,
4758                             lpData, dwDataSize );
4759     checkHR( DPERR_INVALIDPARAMS, hr );
4760     check_messages( pDP[0], idPlayer, 6, &callbackData );
4761     checkStr( "", callbackData.szTrace1 );
4762     check_messages( pDP[1], idPlayer, 6, &callbackData );
4763     checkStr( "", callbackData.szTrace1 );
4764     /* 5 -> g1 */
4765     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[1], 0,
4766                             lpData, dwDataSize );
4767     checkHR( DP_OK, hr );
4768     check_messages( pDP[0], idPlayer, 6, &callbackData );
4769     checkStr( "", callbackData.szTrace1 );
4770     check_messages( pDP[1], idPlayer, 6, &callbackData );
4771     checkStr( "54,53,", callbackData.szTrace1 );
4772     /* 5 -> g2 */
4773     hr = IDirectPlayX_Send( pDP[1], idPlayer[5], idGroup[2], 0,
4774                             lpData, dwDataSize );
4775     checkHR( DP_OK, hr );
4776     check_messages( pDP[0], idPlayer, 6, &callbackData );
4777     checkStr( "", callbackData.szTrace1 );
4778     check_messages( pDP[1], idPlayer, 6, &callbackData );
4779     checkStr( "54,", callbackData.szTrace1 );
4780
4781
4782     HeapFree( GetProcessHeap(), 0, lpData );
4783     IDirectPlayX_Release( pDP[0] );
4784     IDirectPlayX_Release( pDP[1] );
4785
4786 }
4787
4788 /* Send */
4789
4790 static void test_Send(void)
4791 {
4792
4793     LPDIRECTPLAY4 pDP[2];
4794     DPSESSIONDESC2 dpsd;
4795     DPID dpid[4], idFrom, idTo;
4796     CallbackData callbackData;
4797     HRESULT hr;
4798     LPCSTR message = "message";
4799     DWORD messageSize = strlen(message) + 1;
4800     DWORD dwDataSize = 1024;
4801     LPDPMSG_GENERIC lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
4802     LPDPMSG_SECUREMESSAGE lpDataSecure;
4803     UINT i;
4804
4805
4806     for (i=0; i<2; i++)
4807     {
4808         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
4809                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
4810     }
4811     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
4812
4813
4814     /* Uninitialized service provider */
4815     hr = IDirectPlayX_Send( pDP[0], 0, 0, 0,
4816                             (LPVOID) message, messageSize );
4817     checkHR( DPERR_UNINITIALIZED, hr );
4818
4819
4820     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
4821     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
4822
4823     dpsd.dwSize = sizeof(DPSESSIONDESC2);
4824     dpsd.guidApplication = appGuid;
4825     dpsd.dwMaxPlayers = 10;
4826     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4827     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
4828                                pDP[1], 0 );
4829     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
4830
4831
4832     /* Incorrect players */
4833     hr = IDirectPlayX_Send( pDP[0], 0, 1, 2,
4834                             (LPVOID) message, messageSize );
4835     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
4836
4837     if ( hr == DPERR_UNINITIALIZED )
4838     {
4839         todo_wine win_skip( "Send not implemented\n" );
4840         return;
4841     }
4842
4843
4844     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
4845     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
4846     IDirectPlayX_CreatePlayer( pDP[0], &dpid[2], NULL, NULL, NULL, 0, 0 );
4847     IDirectPlayX_CreatePlayer( pDP[1], &dpid[3], NULL, NULL, NULL, 0, 0 );
4848
4849     /* Purge player creation messages */
4850     check_messages( pDP[0], dpid, 4, &callbackData );
4851     checkStr( "S0," "S1,S0," "S2,S1,S0,", callbackData.szTrace1 );
4852     check_messages( pDP[1], dpid, 4, &callbackData );
4853     checkStr( "", callbackData.szTrace1 );
4854
4855
4856     /* Message to self: no error, but no message is sent */
4857     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[0], 0,
4858                             (LPVOID) message, messageSize );
4859     checkHR( DP_OK, hr );
4860
4861     /* Send a message from a remote player */
4862     hr = IDirectPlayX_Send( pDP[1], dpid[0], dpid[1], 0,
4863                             (LPVOID) message, messageSize );
4864     checkHR( DPERR_ACCESSDENIED, hr );
4865     hr = IDirectPlayX_Send( pDP[1], dpid[0], dpid[3], 0,
4866                             (LPVOID) message, messageSize );
4867     checkHR( DPERR_ACCESSDENIED, hr );
4868
4869     /* Null message */
4870     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0,
4871                             NULL, messageSize );
4872     checkHR( DPERR_INVALIDPARAMS, hr );
4873     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0,
4874                             (LPVOID) message, 0 );
4875     checkHR( DPERR_INVALIDPARAMS, hr );
4876
4877
4878     /* Checking no message was sent */
4879     check_messages( pDP[0], dpid, 4, &callbackData );
4880     checkStr( "", callbackData.szTrace1 );
4881     check_messages( pDP[1], dpid, 4, &callbackData );
4882     checkStr( "", callbackData.szTrace1 );
4883
4884
4885     /* Regular parameters */
4886     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4887                             0,
4888                             (LPVOID) message, messageSize );
4889     checkHR( DP_OK, hr );
4890
4891     hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[1],
4892                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4893                                lpData, &dwDataSize );
4894     checkHR( DP_OK, hr );
4895     checkStr( message, (LPSTR) lpData );
4896     check( strlen(message)+1, dwDataSize );
4897
4898     check_messages( pDP[0], dpid, 4, &callbackData );
4899     checkStr( "", callbackData.szTrace1 );
4900     check_messages( pDP[1], dpid, 4, &callbackData );
4901     checkStr( "", callbackData.szTrace1 );
4902
4903
4904     /* Message to a remote player */
4905     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[3], 0,
4906                             (LPVOID) message, messageSize );
4907     checkHR( DP_OK, hr );
4908
4909     hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[3],
4910                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4911                                lpData, &dwDataSize );
4912     checkHR( DPERR_NOMESSAGES, hr );
4913     hr = IDirectPlayX_Receive( pDP[1], &dpid[0], &dpid[3],
4914                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4915                                lpData, &dwDataSize );
4916     checkHR( DP_OK, hr );
4917     checkStr( message, (LPSTR) lpData );
4918     check( strlen(message)+1, dwDataSize );
4919
4920     check_messages( pDP[0], dpid, 4, &callbackData );
4921     checkStr( "", callbackData.szTrace1 );
4922     check_messages( pDP[1], dpid, 4, &callbackData );
4923     checkStr( "", callbackData.szTrace1 );
4924
4925
4926     /* Broadcast */
4927
4928     hr = IDirectPlayX_Send( pDP[0], dpid[0], DPID_ALLPLAYERS, 0,
4929                             (LPVOID) message, messageSize );
4930     checkHR( DP_OK, hr );
4931
4932     for (i=1; i<3; i++)
4933     {
4934         hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[i],
4935                                    DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4936                                    lpData, &dwDataSize );
4937         checkHR( DP_OK, hr );
4938         checkStr( message, (LPSTR) lpData );
4939     }
4940     hr = IDirectPlayX_Receive( pDP[1], &dpid[0], &dpid[3],
4941                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4942                                lpData, &dwDataSize );
4943     checkHR( DP_OK, hr );
4944     checkStr( message, (LPSTR) lpData );
4945
4946     check_messages( pDP[0], dpid, 4, &callbackData );
4947     checkStr( "", callbackData.szTrace1 );
4948     check_messages( pDP[1], dpid, 4, &callbackData );
4949     checkStr( "", callbackData.szTrace1 );
4950
4951
4952     hr = IDirectPlayX_Send( pDP[0], DPID_ALLPLAYERS, dpid[1],
4953                             0,
4954                             (LPVOID) message, messageSize );
4955     checkHR( DPERR_INVALIDPLAYER, hr );
4956     hr = IDirectPlayX_Send( pDP[0], DPID_ALLPLAYERS, DPID_ALLPLAYERS,
4957                             0,
4958                             (LPVOID) message, messageSize );
4959     checkHR( DPERR_INVALIDPLAYER, hr );
4960
4961
4962     /* Flags */
4963     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4964                             DPSEND_GUARANTEED,
4965                             (LPVOID) message, messageSize );
4966     checkHR( DP_OK, hr );
4967
4968     hr = IDirectPlayX_Receive( pDP[0], &dpid[0], &dpid[1],
4969                                DPRECEIVE_FROMPLAYER | DPRECEIVE_TOPLAYER,
4970                                lpData, &dwDataSize );
4971     checkHR( DP_OK, hr );
4972     checkStr( message, (LPSTR)lpData );
4973
4974     /* - Inorrect flags */
4975     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4976                             DPSEND_ENCRYPTED,
4977                             (LPVOID) message, messageSize );
4978     checkHR( DPERR_INVALIDPARAMS, hr );
4979     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4980                             DPSEND_SIGNED,
4981                             (LPVOID) message, messageSize );
4982     checkHR( DPERR_INVALIDPARAMS, hr );
4983     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4984                             DPSEND_ENCRYPTED | DPSEND_SIGNED,
4985                             (LPVOID) message, messageSize );
4986     checkHR( DPERR_INVALIDPARAMS, hr );
4987
4988     /* - Correct flags, but session is not secure */
4989     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4990                             DPSEND_ENCRYPTED | DPSEND_GUARANTEED,
4991                             (LPVOID) message, messageSize );
4992     checkHR( DPERR_INVALIDPARAMS, hr );
4993     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4994                             DPSEND_SIGNED | DPSEND_GUARANTEED,
4995                             (LPVOID) message, messageSize );
4996     checkHR( DPERR_INVALIDPARAMS, hr );
4997     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
4998                             ( DPSEND_ENCRYPTED |
4999                               DPSEND_SIGNED |
5000                               DPSEND_GUARANTEED ),
5001                             (LPVOID) message, messageSize );
5002     checkHR( DPERR_INVALIDPARAMS, hr );
5003
5004     /* - Correct flags, secure session incorrectly opened (without flags) */
5005     hr = IDirectPlayX_Close( pDP[0] );
5006     checkHR( DP_OK, hr );
5007
5008     dpsd.dwFlags = 0;
5009     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
5010     checkHR( DP_OK, hr );
5011     for (i=0; i<2; i++)
5012         IDirectPlayX_CreatePlayer( pDP[0], &dpid[i], NULL, NULL, NULL, 0, 0 );
5013
5014     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5015                             DPSEND_ENCRYPTED | DPSEND_GUARANTEED,
5016                             (LPVOID) message, messageSize );
5017     checkHR( DPERR_INVALIDPARAMS, hr );
5018     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5019                             DPSEND_SIGNED | DPSEND_GUARANTEED,
5020                             (LPVOID) message, messageSize );
5021     checkHR( DPERR_INVALIDPARAMS, hr );
5022     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5023                             ( DPSEND_ENCRYPTED |
5024                               DPSEND_SIGNED |
5025                               DPSEND_GUARANTEED ),
5026                             (LPVOID) message, messageSize );
5027     checkHR( DPERR_INVALIDPARAMS, hr );
5028
5029     /* - Correct flags, secure session */
5030     hr = IDirectPlayX_Close( pDP[0] );
5031     checkHR( DP_OK, hr );
5032
5033     dpsd.dwFlags = DPSESSION_SECURESERVER;
5034     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
5035     checkHR( DP_OK, hr );
5036     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
5037     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
5038
5039     /* Purge */
5040     check_messages( pDP[0], dpid, 6, &callbackData );
5041     checkStr( "S0,", callbackData.szTrace1 );
5042
5043
5044     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5045                             DPSEND_ENCRYPTED | DPSEND_GUARANTEED,
5046                             (LPVOID) message, messageSize );
5047     checkHR( DP_OK, hr );
5048     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5049                             DPSEND_SIGNED | DPSEND_GUARANTEED,
5050                             (LPVOID) message, messageSize );
5051     checkHR( DP_OK, hr );
5052     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5053                             ( DPSEND_ENCRYPTED |
5054                               DPSEND_SIGNED |
5055                               DPSEND_GUARANTEED ),
5056                             (LPVOID) message, messageSize );
5057     checkHR( DP_OK, hr );
5058
5059
5060     for (i=0; i<3; i++)
5061     {
5062         dwDataSize = 1024;
5063         hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, 0, lpData,
5064                                    &dwDataSize );
5065
5066         lpDataSecure = (LPDPMSG_SECUREMESSAGE) lpData;
5067
5068         checkHR( DP_OK, hr );
5069         checkConv( DPSYS_SECUREMESSAGE,   lpData->dwType, dpMsgType2str );
5070         check( DPID_SYSMSG,               idFrom );
5071         check( dpid[1],                   idTo );
5072         check( dpid[0],                   lpDataSecure->dpIdFrom );
5073         checkStr( message,        (LPSTR) lpDataSecure->lpData );
5074         check( strlen(message)+1,         lpDataSecure->dwDataSize );
5075
5076         switch(i)
5077         {
5078         case 0:
5079             checkFlags( DPSEND_ENCRYPTED,
5080                         lpDataSecure->dwFlags,
5081                         FLAGS_DPSEND );
5082             break;
5083         case 1:
5084             checkFlags( DPSEND_SIGNED,
5085                         lpDataSecure->dwFlags,
5086                         FLAGS_DPSEND );
5087             break;
5088         case 2:
5089             checkFlags( DPSEND_SIGNED | DPSEND_ENCRYPTED,
5090                         lpDataSecure->dwFlags,
5091                         FLAGS_DPSEND );
5092             break;
5093         default: break;
5094         }
5095     }
5096     check_messages( pDP[0], dpid, 4, &callbackData );
5097     checkStr( "", callbackData.szTrace1 );
5098
5099
5100     /* - Even in a secure session, incorrect flags still not working */
5101     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5102                             DPSEND_ENCRYPTED,
5103                             (LPVOID) message, messageSize );
5104     checkHR( DPERR_INVALIDPARAMS, hr );
5105     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5106                             DPSEND_SIGNED,
5107                             (LPVOID) message, messageSize );
5108     checkHR( DPERR_INVALIDPARAMS, hr );
5109     hr = IDirectPlayX_Send( pDP[0], dpid[0], dpid[1],
5110                             DPSEND_ENCRYPTED | DPSEND_SIGNED,
5111                             (LPVOID) message, messageSize );
5112     checkHR( DPERR_INVALIDPARAMS, hr );
5113
5114
5115     HeapFree( GetProcessHeap(), 0, lpData );
5116     IDirectPlayX_Release( pDP[0] );
5117     IDirectPlayX_Release( pDP[1] );
5118
5119 }
5120
5121 /* Receive */
5122
5123 static void test_Receive(void)
5124 {
5125
5126     LPDIRECTPLAY4 pDP;
5127     DPSESSIONDESC2 dpsd;
5128     DPID dpid[4], idFrom, idTo;
5129     HRESULT hr;
5130     LPCSTR message = "message";
5131     DWORD messageSize = strlen(message) + 1;
5132     DWORD dwDataSize = 1024;
5133     LPDPMSG_GENERIC lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
5134                                         dwDataSize );
5135     LPDPMSG_CREATEPLAYERORGROUP lpDataCreate;
5136     LPDPMSG_DESTROYPLAYERORGROUP lpDataDestroy;
5137
5138     DWORD dwCount;
5139     UINT i;
5140
5141
5142     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5143                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
5144
5145     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5146     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5147     dpsd.guidApplication = appGuid;
5148
5149     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
5150
5151     IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
5152
5153
5154     /* Invalid parameters */
5155     hr = IDirectPlayX_Receive( pDP, NULL, &idTo, 0,
5156                                lpData, &dwDataSize );
5157     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
5158
5159     if ( hr == DPERR_UNINITIALIZED )
5160     {
5161         todo_wine win_skip( "Receive not implemented\n" );
5162         return;
5163     }
5164
5165     hr = IDirectPlayX_Receive( pDP, &idFrom, NULL, 0,
5166                                lpData, &dwDataSize );
5167     checkHR( DPERR_INVALIDPARAMS, hr );
5168     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5169                                lpData, NULL );
5170     checkHR( DPERR_INVALIDPARAMS, hr );
5171     dwDataSize = -1;
5172     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5173                                lpData, &dwDataSize );
5174     checkHR( DPERR_INVALIDPARAMS, hr );
5175
5176     /* No messages yet */
5177     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5178                                NULL, &dwDataSize );
5179     checkHR( DPERR_NOMESSAGES, hr );
5180     dwDataSize = 0;
5181     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5182                                lpData, &dwDataSize );
5183     checkHR( DPERR_NOMESSAGES, hr );
5184
5185
5186     IDirectPlayX_CreatePlayer( pDP, &dpid[0], NULL, 0, NULL, 0, 0 );
5187     IDirectPlayX_CreatePlayer( pDP, &dpid[1], NULL, 0, NULL, 0,
5188                                DPPLAYER_SPECTATOR );
5189     IDirectPlayX_CreatePlayer( pDP, &dpid[2], NULL, 0, NULL, 0, 0 );
5190     IDirectPlayX_CreatePlayer( pDP, &dpid[3], NULL, 0, NULL, 0, 0 );
5191
5192
5193     /* 0, 1, 2, 3 */
5194     /* 3, 2, 1, 0 */
5195     for (i=0; i<4; i++)
5196     {
5197         IDirectPlayX_GetMessageCount( pDP, dpid[i], &dwCount );
5198         check( 3-i, dwCount );
5199     }
5200
5201
5202     IDirectPlayX_DestroyPlayer( pDP, dpid[3] );
5203     IDirectPlayX_DestroyPlayer( pDP, dpid[1] );
5204
5205
5206     /* 0, 1, 2, 3 */
5207     /* 5, 5, 3, 3 */
5208     IDirectPlayX_GetMessageCount( pDP, dpid[0], &dwCount );
5209     check( 5, dwCount );
5210     IDirectPlayX_GetMessageCount( pDP, dpid[1], &dwCount );
5211     check( 5, dwCount );
5212     IDirectPlayX_GetMessageCount( pDP, dpid[2], &dwCount );
5213     check( 3, dwCount );
5214     IDirectPlayX_GetMessageCount( pDP, dpid[3], &dwCount );
5215     check( 3, dwCount );
5216
5217
5218     /* Buffer too small */
5219     hr = IDirectPlayX_Receive( pDP, &idFrom, &idFrom, 0,
5220                                NULL, &dwDataSize );
5221     checkHR( DPERR_BUFFERTOOSMALL, hr );
5222     check( 48, dwDataSize );
5223     dwDataSize = 0;
5224     hr = IDirectPlayX_Receive( pDP, &idTo, &idFrom, 0,
5225                                lpData, &dwDataSize );
5226     checkHR( DPERR_BUFFERTOOSMALL, hr );
5227     check( 48, dwDataSize );
5228
5229
5230     /* Checking the order or reception */
5231     for (i=0; i<11; i++)
5232     {
5233         dwDataSize = 1024;
5234         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
5235                                    lpData, &dwDataSize );
5236
5237         checkHR( DP_OK, hr );
5238         check( DPID_SYSMSG, idFrom );
5239
5240         if (i<6)  /* Player creation */
5241         {
5242             checkConv( DPSYS_CREATEPLAYERORGROUP, lpData->dwType, dpMsgType2str );
5243             check( 48, dwDataSize );
5244             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5245             check( DPPLAYERTYPE_PLAYER,   lpDataCreate->dwPlayerType );
5246             checkLP( NULL,                lpDataCreate->lpData );
5247             check( 0,                     lpDataCreate->dwDataSize );
5248             checkLP( NULL,                U1(lpDataCreate->dpnName).lpszShortNameA );
5249             check( 0,                     lpDataCreate->dpIdParent );
5250         }
5251         else  /* Player destruction */
5252         {
5253             checkConv( DPSYS_DESTROYPLAYERORGROUP, lpData->dwType,
5254                        dpMsgType2str );
5255             check( 52, dwDataSize );
5256             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5257             check( DPPLAYERTYPE_PLAYER,   lpDataDestroy->dwPlayerType );
5258             checkLP( NULL,                lpDataDestroy->lpLocalData );
5259             check( 0,                     lpDataDestroy->dwLocalDataSize );
5260             checkLP( NULL,                lpDataDestroy->lpRemoteData );
5261             check( 0,                     lpDataDestroy->dwRemoteDataSize );
5262             checkLP( NULL,                U1(lpDataDestroy->dpnName).lpszShortNameA );
5263             check( 0,                     lpDataDestroy->dpIdParent );
5264         }
5265
5266         switch(i)
5267         {
5268             /* 1 -> 0 */
5269         case 0:
5270             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5271             check( dpid[0], idTo );
5272             check( dpid[1],              lpDataCreate->dpId );
5273             check( 1,                    lpDataCreate->dwCurrentPlayers );
5274             checkFlags( DPPLAYER_LOCAL|DPPLAYER_SPECTATOR, lpDataCreate->dwFlags,
5275                         FLAGS_DPPLAYER|FLAGS_DPGROUP );
5276             break;
5277
5278             /* 2 -> 1,0 */
5279         case 1:
5280             check( dpid[1], idTo );
5281             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5282             check( dpid[2],              lpDataCreate->dpId );
5283             check( 2,                    lpDataCreate->dwCurrentPlayers );
5284             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5285                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5286             break;
5287         case 2:
5288             check( dpid[0], idTo );
5289             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5290             check( dpid[2],              lpDataCreate->dpId );
5291             check( 2,                    lpDataCreate->dwCurrentPlayers );
5292             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5293                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5294             break;
5295
5296             /* 3 -> 2,1,0 */
5297         case 3:
5298             check( dpid[2], idTo );
5299             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5300             check( dpid[3],              lpDataCreate->dpId );
5301             check( 3,                    lpDataCreate->dwCurrentPlayers );
5302             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5303                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5304             break;
5305         case 4:
5306             check( dpid[1], idTo );
5307             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5308             check( dpid[3],              lpDataCreate->dpId );
5309             check( 3,                    lpDataCreate->dwCurrentPlayers );
5310             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5311                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5312             break;
5313         case 5:
5314             check( dpid[0], idTo );
5315             lpDataCreate = (LPDPMSG_CREATEPLAYERORGROUP) lpData;
5316             check( dpid[3],              lpDataCreate->dpId );
5317             check( 3,                    lpDataCreate->dwCurrentPlayers );
5318             checkFlags( DPPLAYER_LOCAL,  lpDataCreate->dwFlags,
5319                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5320             break;
5321
5322             /* 3 -> 2,1,0 */
5323         case 6:
5324             check( dpid[2], idTo );
5325             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5326             check( dpid[3],              lpDataDestroy->dpId );
5327             checkFlags( DPPLAYER_LOCAL,  lpDataDestroy->dwFlags,
5328                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5329             break;
5330         case 7:
5331             check( dpid[1], 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 8:
5338             check( dpid[0], 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
5345             /* 1 -> 2,0 */
5346         case 9:
5347             check( dpid[2], idTo );
5348             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5349             check( dpid[1],                 lpDataDestroy->dpId );
5350             checkFlags( DPPLAYER_LOCAL |
5351                         DPPLAYER_SPECTATOR, lpDataDestroy->dwFlags,
5352                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5353             break;
5354         case 10:
5355             check( dpid[0], idTo );
5356             lpDataDestroy = (LPDPMSG_DESTROYPLAYERORGROUP) lpData;
5357             check( dpid[1],                 lpDataDestroy->dpId );
5358             checkFlags( DPPLAYER_LOCAL |
5359                         DPPLAYER_SPECTATOR, lpDataDestroy->dwFlags,
5360                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
5361             break;
5362
5363         default:
5364             trace( "%s\n", dpMsgType2str(lpData->dwType) );
5365             break;
5366         }
5367     }
5368
5369     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpData, &dwDataSize );
5370     checkHR( DPERR_NOMESSAGES, hr );
5371
5372
5373     /* New data message */
5374     hr = IDirectPlayX_Send( pDP, dpid[0], dpid[2], 0,
5375                             (LPVOID) message, messageSize );
5376     checkHR( DP_OK, hr );
5377
5378
5379     /* Ensuring DPRECEIVE_PEEK doesn't remove the messages from the queue */
5380     for (i=0; i<10; i++)
5381     {
5382         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, DPRECEIVE_PEEK,
5383                                    lpData, &dwDataSize );
5384         checkHR( DP_OK, hr );
5385         checkStr( message, (LPSTR) lpData );
5386     }
5387
5388     /* Removing the message from the queue */
5389     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpData, &dwDataSize );
5390     checkHR( DP_OK, hr );
5391     check( idFrom, dpid[0] );
5392     check( idTo, dpid[2] );
5393     checkStr( message, (LPSTR) lpData );
5394
5395     hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpData, &dwDataSize );
5396     checkHR( DPERR_NOMESSAGES, hr );
5397
5398
5399     HeapFree( GetProcessHeap(), 0, lpData );
5400     IDirectPlayX_Release( pDP );
5401
5402 }
5403
5404 /* GetMessageCount */
5405
5406 static void test_GetMessageCount(void)
5407 {
5408
5409     LPDIRECTPLAY4 pDP[2];
5410     DPSESSIONDESC2 dpsd;
5411     DPID dpid[4];
5412     HRESULT hr;
5413     UINT i;
5414     DWORD dwCount;
5415
5416     DWORD dwDataSize = 1024;
5417     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
5418     CallbackData callbackData;
5419
5420
5421     for (i=0; i<2; i++)
5422     {
5423         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5424                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
5425     }
5426     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5427
5428     dwCount = -1;
5429     hr = IDirectPlayX_GetMessageCount( pDP[0], 0,  &dwCount );
5430     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
5431     check( -1, dwCount );
5432
5433     if ( hr == DP_OK )
5434     {
5435         todo_wine win_skip( "GetMessageCount not implemented\n" );
5436         return;
5437     }
5438
5439
5440     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
5441     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
5442
5443
5444     dwCount = -1;
5445     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5446     checkHR( DP_OK, hr );
5447     check( 0, dwCount );
5448
5449
5450     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5451     dpsd.guidApplication = appGuid;
5452     dpsd.dwMaxPlayers = 10;
5453     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
5454     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
5455                                pDP[1], 0 );
5456
5457     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
5458     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
5459     IDirectPlayX_CreatePlayer( pDP[1], &dpid[3], NULL, NULL, NULL, 0, 0 );
5460     IDirectPlayX_CreatePlayer( pDP[0], &dpid[2], NULL, NULL, NULL, 0, 0 );
5461
5462
5463     /* Incorrect parameters */
5464     dwCount = -1;
5465     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], NULL );
5466     checkHR( DPERR_INVALIDPARAMS, hr );
5467     check( -1, dwCount );
5468
5469     dwCount = -1;
5470     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, NULL );
5471     checkHR( DPERR_INVALIDPARAMS, hr );
5472     check( -1, dwCount );
5473
5474     dwCount = -1;
5475     hr = IDirectPlayX_GetMessageCount( pDP[0], -1, &dwCount );
5476     checkHR( DPERR_INVALIDPLAYER, hr );
5477     check( -1, dwCount );
5478
5479
5480     /* Correct parameters */
5481     /* Player creation messages */
5482     dwCount = -1;
5483     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5484     checkHR( DP_OK, hr );
5485     check( 5, dwCount );
5486
5487     dwCount = -1;
5488     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5489     checkHR( DP_OK, hr );
5490     check( 1, dwCount );
5491
5492     dwCount = -1;
5493     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
5494     checkHR( DP_OK, hr );
5495     check( 3, dwCount );
5496
5497     dwCount = -1;
5498     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5499     checkHR( DP_OK, hr );
5500     check( 2, dwCount );
5501
5502     dwCount = -1;
5503     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[3], &dwCount );
5504     checkHR( DP_OK, hr );
5505     /* Remote player: doesn't throw error but result is 0 and not 1 */
5506     check( 0, dwCount );
5507
5508     dwCount = -1;
5509     hr = IDirectPlayX_GetMessageCount( pDP[1], dpid[3], &dwCount );
5510     checkHR( DP_OK, hr );
5511     check( 1, dwCount );
5512
5513     dwCount = -1;
5514     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5515     checkHR( DP_OK, hr );
5516     check( 2, dwCount );
5517
5518
5519     /* Purge queues */
5520     check_messages( pDP[0], dpid, 6, &callbackData );
5521     checkStr( "S0,S1,S0,S1,S0,", callbackData.szTrace1 );
5522     check_messages( pDP[1], dpid, 6, &callbackData );
5523     checkStr( "S3,", callbackData.szTrace1 );
5524
5525
5526     /* Ensure queues is purged */
5527     dwCount = -1;
5528     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5529     checkHR( DP_OK, hr );
5530     check( 0, dwCount );
5531
5532     dwCount = -1;
5533     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5534     checkHR( DP_OK, hr );
5535     check( 0, dwCount );
5536
5537
5538     /* Send data messages */
5539     for (i=0; i<5; i++)
5540         IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0, lpData, dwDataSize );
5541     for (i=0; i<6; i++)
5542         IDirectPlayX_Send( pDP[0], dpid[1], dpid[2], 0, lpData, dwDataSize );
5543     for (i=0; i<7; i++)
5544         IDirectPlayX_Send( pDP[0], dpid[2], dpid[3], 0, lpData, dwDataSize );
5545
5546
5547     /* Check all messages are in the queues */
5548     dwCount = -1;
5549     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5550     checkHR( DP_OK, hr );
5551     check( 11, dwCount );
5552
5553     dwCount = -1;
5554     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5555     checkHR( DP_OK, hr );
5556     check( 7, dwCount );
5557
5558     dwCount = -1;
5559     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
5560     checkHR( DP_OK, hr );
5561     check( 0, dwCount );
5562
5563     dwCount = -1;
5564     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5565     checkHR( DP_OK, hr );
5566     check( 5, dwCount );
5567
5568     dwCount = -1;
5569     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[2], &dwCount );
5570     checkHR( DP_OK, hr );
5571     check( 6, dwCount );
5572
5573     dwCount = -1;
5574     hr = IDirectPlayX_GetMessageCount( pDP[1], dpid[3], &dwCount );
5575     checkHR( DP_OK, hr );
5576     check( 7, dwCount );
5577
5578
5579     /* Purge queues again */
5580     check_messages( pDP[0], dpid, 6, &callbackData );
5581     checkStr( "01,01,01,01,01,"
5582               "12,12,12,12,12,12,", callbackData.szTrace1 );
5583     check_messages( pDP[1], dpid, 6, &callbackData );
5584     checkStr( "23,23,23,23,23,23,23,", callbackData.szTrace1 );
5585
5586
5587     /* Check queues are purged */
5588     dwCount = -1;
5589     hr = IDirectPlayX_GetMessageCount( pDP[0], 0, &dwCount );
5590     checkHR( DP_OK, hr );
5591     check( 0, dwCount );
5592
5593     dwCount = -1;
5594     hr = IDirectPlayX_GetMessageCount( pDP[1], 0, &dwCount );
5595     checkHR( DP_OK, hr );
5596     check( 0, dwCount );
5597
5598     dwCount = -1;
5599     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
5600     checkHR( DP_OK, hr );
5601     check( 0, dwCount );
5602
5603     dwCount = -1;
5604     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[1], &dwCount );
5605     checkHR( DP_OK, hr );
5606     check( 0, dwCount );
5607
5608     dwCount = -1;
5609     hr = IDirectPlayX_GetMessageCount( pDP[0], dpid[2], &dwCount );
5610     checkHR( DP_OK, hr );
5611     check( 0, dwCount );
5612
5613     dwCount = -1;
5614     hr = IDirectPlayX_GetMessageCount( pDP[1], dpid[3], &dwCount );
5615     checkHR( DP_OK, hr );
5616     check( 0, dwCount );
5617
5618
5619     HeapFree( GetProcessHeap(), 0, lpData );
5620     IDirectPlayX_Release( pDP[0] );
5621     IDirectPlayX_Release( pDP[1] );
5622
5623 }
5624
5625 /* GetMessageQueue */
5626
5627 static void test_GetMessageQueue(void)
5628 {
5629
5630     LPDIRECTPLAY4 pDP[2];
5631     DPSESSIONDESC2 dpsd;
5632     DPID dpid[4];
5633     CallbackData callbackData;
5634     HRESULT hr;
5635     UINT i;
5636     DWORD dwNumMsgs, dwNumBytes;
5637
5638     DWORD dwDataSize = 1024;
5639     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
5640
5641
5642     for (i=0; i<2; i++)
5643     {
5644         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5645                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
5646     }
5647     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5648
5649
5650     dwNumMsgs = dwNumBytes = -1;
5651     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0, 0,
5652                                        &dwNumMsgs, &dwNumBytes );
5653     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
5654     check( -1, dwNumMsgs );
5655     check( -1, dwNumBytes );
5656
5657     if ( hr == DP_OK )
5658     {
5659         todo_wine win_skip( "GetMessageQueue not implemented\n" );
5660         return;
5661     }
5662
5663
5664     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
5665     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
5666
5667
5668     dwNumMsgs = dwNumBytes = -1;
5669     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0, 0,
5670                                        &dwNumMsgs, &dwNumBytes );
5671     checkHR( DP_OK, hr );
5672     check( 0, dwNumMsgs );
5673     check( 0, dwNumBytes );
5674
5675
5676     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5677     dpsd.guidApplication = appGuid;
5678     dpsd.dwMaxPlayers = 10;
5679     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
5680     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
5681                                pDP[1], 0 );
5682
5683     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
5684     IDirectPlayX_CreatePlayer( pDP[0], &dpid[1], NULL, NULL, NULL, 0, 0 );
5685     IDirectPlayX_CreatePlayer( pDP[1], &dpid[3], NULL, NULL, NULL, 0, 0 );
5686     IDirectPlayX_CreatePlayer( pDP[0], &dpid[2], NULL, NULL, NULL, 0, 0 );
5687
5688
5689
5690     /* Incorrect parameters */
5691     dwNumMsgs = dwNumBytes = -1;
5692     hr = IDirectPlayX_GetMessageQueue( pDP[0], -1, dpid[1],
5693                                        0,
5694                                        &dwNumMsgs, &dwNumBytes );
5695     checkHR( DPERR_INVALIDPLAYER, hr );
5696     check( -1, dwNumMsgs );
5697     check( -1, dwNumBytes );
5698
5699     dwNumMsgs = dwNumBytes = -1;
5700     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], -1,
5701                                        0,
5702                                        &dwNumMsgs, &dwNumBytes );
5703     checkHR( DPERR_INVALIDPLAYER, hr );
5704     check( -1, dwNumMsgs );
5705     check( -1, dwNumBytes );
5706
5707     dwNumMsgs = dwNumBytes = -1;
5708     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[0],
5709                                        -1,
5710                                        &dwNumMsgs, &dwNumBytes );
5711     checkHR( DPERR_INVALIDFLAGS, hr );
5712     check( -1, dwNumMsgs );
5713     check( -1, dwNumBytes );
5714
5715     dwNumMsgs = dwNumBytes = -1;
5716     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5717                                        ( DPMESSAGEQUEUE_SEND |
5718                                          DPMESSAGEQUEUE_RECEIVE ),
5719                                        &dwNumMsgs, &dwNumBytes );
5720     checkHR( DPERR_INVALIDFLAGS, hr );
5721     check( -1, dwNumMsgs );
5722     check( -1, dwNumBytes );
5723
5724     /* - Remote players */
5725     dwNumMsgs = dwNumBytes = -1;
5726     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, dpid[3],
5727                                        DPMESSAGEQUEUE_RECEIVE,
5728                                        &dwNumMsgs, &dwNumBytes );
5729     checkHR( DPERR_INVALIDPLAYER, hr ); /* Player 3 is remote */
5730     check( -1, dwNumMsgs );
5731     check( -1, dwNumBytes );
5732
5733     dwNumMsgs = dwNumBytes = -1;
5734     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[3], 0,
5735                                        DPMESSAGEQUEUE_SEND,
5736                                        &dwNumMsgs, &dwNumBytes );
5737     checkHR( DPERR_INVALIDPLAYER, hr ); /* Player 3 is remote */
5738     check( -1, dwNumMsgs );
5739     check( -1, dwNumBytes );
5740
5741     /* - Remote players, this time in the right place */
5742     dwNumMsgs = dwNumBytes = -1;
5743     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, dpid[3],
5744                                        DPMESSAGEQUEUE_SEND,
5745                                        &dwNumMsgs, &dwNumBytes );
5746     checkHR( DP_OK, hr );
5747     check( 0, dwNumMsgs );
5748     check( 0, dwNumBytes );
5749
5750     dwNumMsgs = dwNumBytes = -1;
5751     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[3], 0,
5752                                        DPMESSAGEQUEUE_RECEIVE,
5753                                        &dwNumMsgs, &dwNumBytes );
5754     checkHR( DP_OK, hr );
5755     check( 0, dwNumMsgs );
5756     check( 0, dwNumBytes );
5757
5758
5759     /* Correct parameters */
5760     dwNumMsgs = dwNumBytes = -1;
5761     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, dpid[1],
5762                                        DPMESSAGEQUEUE_RECEIVE,
5763                                        &dwNumMsgs, &dwNumBytes );
5764     checkHR( DP_OK, hr );
5765     check( 2, dwNumMsgs );
5766     check( 96, dwNumBytes );
5767
5768     dwNumMsgs = dwNumBytes = -1;
5769     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], 0,
5770                                        DPMESSAGEQUEUE_RECEIVE,
5771                                        &dwNumMsgs, &dwNumBytes );
5772     checkHR( DP_OK, hr );
5773     check( 0, dwNumMsgs );
5774     check( 0, dwNumBytes );
5775
5776     dwNumMsgs = dwNumBytes = -1;
5777     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0,
5778                                        DPMESSAGEQUEUE_RECEIVE,
5779                                        &dwNumMsgs, &dwNumBytes );
5780     checkHR( DP_OK, hr );
5781     check( 5, dwNumMsgs );
5782     check( 240, dwNumBytes );
5783
5784     dwNumMsgs = dwNumBytes = -1;
5785     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5786                                        DPMESSAGEQUEUE_RECEIVE,
5787                                        NULL, &dwNumBytes );
5788     checkHR( DP_OK, hr );
5789     check( -1, dwNumMsgs );
5790     check( 0, dwNumBytes );
5791
5792     dwNumMsgs = dwNumBytes = -1;
5793     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5794                                        DPMESSAGEQUEUE_RECEIVE,
5795                                        &dwNumMsgs, NULL );
5796     checkHR( DP_OK, hr );
5797     check( 0, dwNumMsgs );
5798     check( -1, dwNumBytes );
5799
5800     dwNumMsgs = dwNumBytes = -1;
5801     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5802                                        DPMESSAGEQUEUE_RECEIVE,
5803                                        NULL, NULL );
5804     checkHR( DP_OK, hr );
5805     check( -1, dwNumMsgs );
5806     check( -1, dwNumBytes );
5807
5808     dwNumMsgs = dwNumBytes = -1;
5809     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5810                                        DPMESSAGEQUEUE_RECEIVE,
5811                                        &dwNumMsgs, &dwNumBytes );
5812     checkHR( DP_OK, hr );
5813     check( 0, dwNumMsgs );
5814     check( 0, dwNumBytes );
5815
5816
5817     /* Purge messages */
5818     check_messages( pDP[0], dpid, 6, &callbackData );
5819     checkStr( "S0,S1,S0,S1,S0,", callbackData.szTrace1 );
5820     check_messages( pDP[1], dpid, 6, &callbackData );
5821     checkStr( "S3,", callbackData.szTrace1 );
5822
5823     /* Check queues are empty */
5824     dwNumMsgs = dwNumBytes = -1;
5825     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0,
5826                                        DPMESSAGEQUEUE_RECEIVE,
5827                                        &dwNumMsgs, &dwNumBytes );
5828     checkHR( DP_OK, hr );
5829     check( 0, dwNumMsgs );
5830     check( 0, dwNumBytes );
5831
5832
5833     /* Sending 4 data messages from 0 to 1 */
5834     /*         3               from 0 to 3 */
5835     /*         2               from 1 to 3 */
5836     for (i=0; i<4; i++)
5837         IDirectPlayX_Send( pDP[0], dpid[0], dpid[1], 0, lpData, dwDataSize );
5838     for (i=0; i<3; i++)
5839         IDirectPlayX_Send( pDP[0], dpid[0], dpid[3], 0, lpData, dwDataSize );
5840     for (i=0; i<2; i++)
5841         IDirectPlayX_Send( pDP[0], dpid[1], dpid[3], 0, lpData, dwDataSize );
5842
5843
5844     dwNumMsgs = dwNumBytes = -1;
5845     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5846                                        DPMESSAGEQUEUE_RECEIVE,
5847                                        &dwNumMsgs, &dwNumBytes );
5848     checkHR( DP_OK, hr );
5849     check( 4, dwNumMsgs );
5850     check( 4*dwDataSize, dwNumBytes );
5851
5852     dwNumMsgs = dwNumBytes = -1;
5853     hr = IDirectPlayX_GetMessageQueue( pDP[1], dpid[0], dpid[3],
5854                                        DPMESSAGEQUEUE_RECEIVE,
5855                                        &dwNumMsgs, &dwNumBytes );
5856     checkHR( DP_OK, hr );
5857     check( 3, dwNumMsgs );
5858     check( 3*dwDataSize, dwNumBytes );
5859
5860     dwNumMsgs = dwNumBytes = -1;
5861     hr = IDirectPlayX_GetMessageQueue( pDP[1], dpid[1], dpid[3],
5862                                        DPMESSAGEQUEUE_RECEIVE,
5863                                        &dwNumMsgs, &dwNumBytes );
5864     checkHR( DP_OK, hr );
5865     check( 2, dwNumMsgs );
5866     check( 2*dwDataSize, dwNumBytes );
5867
5868     dwNumMsgs = dwNumBytes = -1;
5869     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], 0,
5870                                        DPMESSAGEQUEUE_RECEIVE,
5871                                        &dwNumMsgs, &dwNumBytes );
5872     checkHR( DP_OK, hr );
5873     check( 4, dwNumMsgs );
5874     check( 4*dwDataSize, dwNumBytes );
5875
5876     dwNumMsgs = dwNumBytes = -1;
5877     hr = IDirectPlayX_GetMessageQueue( pDP[1], dpid[0], 0,
5878                                        DPMESSAGEQUEUE_RECEIVE,
5879                                        &dwNumMsgs, &dwNumBytes );
5880     checkHR( DP_OK, hr );
5881     check( 3, dwNumMsgs );
5882     check( 3*dwDataSize, dwNumBytes );
5883
5884     dwNumMsgs = dwNumBytes = -1;
5885     hr = IDirectPlayX_GetMessageQueue( pDP[1], 0, dpid[3],
5886                                        DPMESSAGEQUEUE_RECEIVE,
5887                                        &dwNumMsgs, &dwNumBytes );
5888     checkHR( DP_OK, hr );
5889     check( 5, dwNumMsgs );
5890     check( 5*dwDataSize, dwNumBytes );
5891
5892     dwNumMsgs = dwNumBytes = -1;
5893     hr = IDirectPlayX_GetMessageQueue( pDP[0], 0, 0,
5894                                        DPMESSAGEQUEUE_RECEIVE,
5895                                        &dwNumMsgs, &dwNumBytes );
5896     checkHR( DP_OK, hr );
5897     check( 4, dwNumMsgs );
5898     check( 4*dwDataSize, dwNumBytes );
5899
5900     dwNumMsgs = dwNumBytes = -1;
5901     hr = IDirectPlayX_GetMessageQueue( pDP[1], 0, 0,
5902                                        DPMESSAGEQUEUE_RECEIVE,
5903                                        &dwNumMsgs, &dwNumBytes );
5904     checkHR( DP_OK, hr );
5905     check( 5, dwNumMsgs );
5906     check( 5*dwDataSize, dwNumBytes );
5907
5908
5909     dwNumMsgs = dwNumBytes = -1;
5910     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5911                                        DPMESSAGEQUEUE_SEND,
5912                                        &dwNumMsgs, &dwNumBytes );
5913     checkHR( DP_OK, hr );
5914     check( 0, dwNumMsgs );
5915     check( 0, dwNumBytes );
5916
5917     dwNumMsgs = dwNumBytes = -1;
5918     hr = IDirectPlayX_GetMessageQueue( pDP[0], dpid[0], dpid[1],
5919                                        0,
5920                                        &dwNumMsgs, &dwNumBytes );
5921     checkHR( DP_OK, hr );
5922     check( 0, dwNumMsgs );
5923     check( 0, dwNumBytes );
5924
5925
5926     HeapFree( GetProcessHeap(), 0, lpData );
5927     IDirectPlayX_Release( pDP[0] );
5928     IDirectPlayX_Release( pDP[1] );
5929
5930 }
5931
5932 /* Remote data replication */
5933
5934 static void test_remote_data_replication(void)
5935 {
5936
5937     LPDIRECTPLAY4 pDP[2];
5938     DPSESSIONDESC2 dpsd;
5939     DPID dpid[2], idFrom, idTo;
5940     CallbackData callbackData;
5941     HRESULT hr;
5942     UINT i, j;
5943     DWORD dwFlags, dwDataSize = 1024;
5944     DWORD dwCount;
5945
5946     LPDPMSG_SETPLAYERORGROUPDATA lpData = HeapAlloc( GetProcessHeap(),
5947                                                      HEAP_ZERO_MEMORY,
5948                                                      dwDataSize );
5949
5950     LPCSTR lpDataLocal[] = { "local_0", "local_1" };
5951     LPCSTR lpDataRemote[] = { "remote_0", "remote_1" };
5952     LPCSTR lpDataFake = "ugly_fake_data";
5953     LPSTR lpDataGet = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 32 );
5954     DWORD dwDataSizeLocal = strlen(lpDataLocal[0])+1,
5955         dwDataSizeRemote = strlen(lpDataRemote[0])+1,
5956         dwDataSizeFake = strlen(lpDataFake)+1,
5957         dwDataSizeGet;
5958
5959
5960     for (i=0; i<2; i++)
5961     {
5962         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
5963                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
5964         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
5965     }
5966     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
5967     dpsd.dwSize = sizeof(DPSESSIONDESC2);
5968     dpsd.guidApplication = appGuid;
5969
5970     /* Host */
5971     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
5972     todo_wine checkHR( DP_OK, hr );
5973
5974     if ( hr == DPERR_UNINITIALIZED )
5975     {
5976         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
5977         return;
5978     }
5979
5980     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
5981                                     NULL, NULL, NULL, 0, 0 );
5982     checkHR( DP_OK, hr );
5983
5984     /* Peer */
5985     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
5986                                     pDP[1], 0 );
5987     checkHR( DP_OK, hr );
5988
5989     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
5990                                     NULL, NULL, NULL, 0, 0 );
5991     checkHR( DP_OK, hr );
5992
5993     /* Check players */
5994     for (i=0; i<2; i++)
5995     {
5996         /* Local (0,0) (1,1) */
5997         IDirectPlayX_GetPlayerFlags( pDP[i], dpid[i], &dwFlags );
5998         checkFlags( DPPLAYER_LOCAL, dwFlags, FLAGS_DPPLAYER );
5999         /* Remote (0,1) (1,0) */
6000         IDirectPlayX_GetPlayerFlags( pDP[i], dpid[!i], &dwFlags );
6001         checkFlags( 0, dwFlags, FLAGS_DPPLAYER );
6002     }
6003
6004     /* Set data for a local player */
6005     for (i=0; i<2; i++)
6006     {
6007         hr = IDirectPlayX_SetPlayerData( pDP[i], dpid[i],
6008                                          (LPVOID) lpDataLocal[i],
6009                                          dwDataSizeLocal,
6010                                          DPSET_LOCAL );
6011         checkHR( DP_OK, hr );
6012         hr = IDirectPlayX_SetPlayerData( pDP[i], dpid[i],
6013                                          (LPVOID) lpDataRemote[i],
6014                                          dwDataSizeRemote,
6015                                          DPSET_REMOTE );
6016         checkHR( DP_OK, hr );
6017     }
6018
6019     /* Retrieve data locally (0->0, 1->1) */
6020     for (i=0; i<2; i++)
6021     {
6022         dwDataSizeGet = dwDataSizeFake;
6023         strcpy( lpDataGet, lpDataFake );
6024         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[i],
6025                                          lpDataGet, &dwDataSizeGet,
6026                                          DPGET_LOCAL );
6027         checkHR( DP_OK, hr );
6028         check( dwDataSizeLocal, dwDataSizeGet );
6029         checkStr( lpDataLocal[i], lpDataGet );
6030
6031         dwDataSizeGet = dwDataSizeFake;
6032         strcpy( lpDataGet, lpDataFake );
6033         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[i],
6034                                          lpDataGet, &dwDataSizeGet,
6035                                          DPGET_REMOTE );
6036         checkHR( DP_OK, hr );
6037         check( dwDataSizeRemote, dwDataSizeGet );
6038         checkStr( lpDataRemote[i], lpDataGet );
6039     }
6040
6041
6042     /* Set data for a remote player */
6043     /* This should fail with DPERR_ACCESSDENIED,
6044        but for some reason it doesn't */
6045     for (i=0; i<2; i++)
6046     {
6047         IDirectPlayX_SetPlayerData( pDP[i], dpid[!i],
6048                                     (LPVOID) lpDataLocal[!i],
6049                                     dwDataSizeLocal,
6050                                     DPSET_LOCAL );
6051         checkHR( DP_OK, hr );
6052         IDirectPlayX_SetPlayerData( pDP[i], dpid[!i],
6053                                     (LPVOID) lpDataRemote[!i],
6054                                     dwDataSizeRemote,
6055                                     DPSET_REMOTE );
6056         checkHR( DP_OK, hr );
6057     }
6058
6059     /* Retrieve crossed data (0->1, 1->0) */
6060     for (i=0; i<2; i++)
6061     {
6062         dwDataSizeGet = dwDataSizeFake;
6063         strcpy( lpDataGet, lpDataFake );
6064         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[!i],
6065                                          lpDataGet, &dwDataSizeGet,
6066                                          DPGET_LOCAL );
6067         checkHR( DP_OK, hr );
6068         check( dwDataSizeLocal, dwDataSizeGet );
6069         checkStr( lpDataLocal[!i], lpDataGet );
6070
6071         dwDataSizeGet = dwDataSizeFake;
6072         strcpy( lpDataGet, lpDataFake );
6073         hr = IDirectPlayX_GetPlayerData( pDP[i], dpid[!i],
6074                                          lpDataGet, &dwDataSizeGet,
6075                                          DPGET_REMOTE );
6076         checkHR( DP_OK, hr );
6077         check( dwDataSizeRemote, dwDataSizeGet );
6078         checkStr( lpDataRemote[!i], lpDataGet );
6079     }
6080
6081
6082     /* Purge "new player" messages from queue */
6083     hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, 0, lpData, &dwDataSize );
6084     checkHR( DP_OK, hr );
6085     checkConv( DPSYS_CREATEPLAYERORGROUP, lpData->dwType, dpMsgType2str );
6086
6087     /* Check number of messages in queue */
6088     for (i=0; i<2; i++)
6089     {
6090         IDirectPlayX_GetMessageCount( pDP[i], dpid[i], &dwCount );
6091         check( 2, dwCount );
6092         IDirectPlayX_GetMessageCount( pDP[i], dpid[!i], &dwCount );
6093         check( 0, dwCount );
6094     }
6095
6096     /* Checking system messages */
6097     for (i=0; i<2; i++)
6098     {
6099         for (j=0; j<2; j++)
6100         {
6101             hr = IDirectPlayX_Receive( pDP[i], &idFrom, &idTo, 0, lpData,
6102                                        &dwDataSize );
6103             checkHR( DP_OK, hr );
6104             check( 29, dwDataSize );
6105             check( DPID_SYSMSG, idFrom );
6106             check( dpid[i], idTo );
6107             checkConv( DPSYS_SETPLAYERORGROUPDATA, lpData->dwType,
6108                        dpMsgType2str );
6109             check( DPPLAYERTYPE_PLAYER,            lpData->dwPlayerType );
6110             check( dpid[j],                        lpData->dpId );
6111             checkStr( lpDataRemote[j],     (LPSTR) lpData->lpData );
6112             check( dwDataSizeRemote,               lpData->dwDataSize );
6113             dwDataSize = 1024;
6114         }
6115         hr = IDirectPlayX_Receive( pDP[i], &idFrom, &idTo, 0,
6116                                    lpData, &dwDataSize );
6117         checkHR( DPERR_NOMESSAGES, hr );
6118     }
6119
6120
6121     /* Changing remote data */
6122     hr = IDirectPlayX_SetPlayerData( pDP[0], dpid[0],
6123                                      (LPVOID) lpDataRemote[0], dwDataSizeRemote,
6124                                      DPSET_REMOTE );
6125     checkHR( DP_OK, hr );
6126
6127     /* Checking system messages (j=0) */
6128     for (i=0; i<2; i++)
6129     {
6130         hr = IDirectPlayX_Receive( pDP[i], &idFrom, &idTo, 0,
6131                                    lpData, &dwDataSize );
6132         checkHR( DP_OK, hr );
6133         check( 29, dwDataSize );
6134         check( DPID_SYSMSG, idFrom );
6135         check( dpid[i], idTo );
6136         checkConv( DPSYS_SETPLAYERORGROUPDATA, lpData->dwType, dpMsgType2str );
6137         check( DPPLAYERTYPE_PLAYER,            lpData->dwPlayerType );
6138         check( dpid[0],                        lpData->dpId );
6139         checkStr( lpDataRemote[0],     (LPSTR) lpData->lpData );
6140         check( dwDataSizeRemote,               lpData->dwDataSize );
6141         dwDataSize = 1024;
6142     }
6143
6144     /* Queue is empty */
6145     check_messages( pDP[0], dpid, 2, &callbackData );
6146     checkStr( "", callbackData.szTrace1 );
6147     check_messages( pDP[1], dpid, 2, &callbackData );
6148     checkStr( "", callbackData.szTrace1 );
6149
6150
6151     HeapFree( GetProcessHeap(), 0, lpDataGet );
6152     HeapFree( GetProcessHeap(), 0, lpData );
6153     IDirectPlayX_Release( pDP[0] );
6154     IDirectPlayX_Release( pDP[1] );
6155
6156 }
6157
6158 /* Host migration */
6159
6160 static void test_host_migration(void)
6161 {
6162
6163     LPDIRECTPLAY4 pDP[2];
6164     DPSESSIONDESC2 dpsd;
6165     DPID dpid[2], idFrom, idTo;
6166     HRESULT hr;
6167     UINT i;
6168     DWORD dwCount;
6169
6170     DWORD dwDataSize = 1024;
6171     LPDPMSG_DESTROYPLAYERORGROUP lpData = HeapAlloc( GetProcessHeap(),
6172                                                      HEAP_ZERO_MEMORY,
6173                                                      dwDataSize );
6174
6175
6176     for (i=0; i<2; i++)
6177     {
6178         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
6179                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
6180         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
6181     }
6182     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
6183     dpsd.dwSize = sizeof(DPSESSIONDESC2);
6184     dpsd.guidApplication = appGuid;
6185     dpsd.dwMaxPlayers = 10;
6186     dpsd.dwFlags = DPSESSION_MIGRATEHOST;
6187
6188     /* Host */
6189     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
6190     todo_wine checkHR( DP_OK, hr );
6191
6192     if ( hr != DP_OK )
6193     {
6194         todo_wine win_skip( "dplay not implemented enough for this test yet\n" );
6195         return;
6196     }
6197
6198     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
6199     checkHR( DP_OK, hr );
6200
6201     /* Peer */
6202     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
6203                                     pDP[1], 0 );
6204     checkHR( DP_OK, hr );
6205
6206     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1], NULL, NULL, NULL, 0, 0 );
6207     checkHR( DP_OK, hr );
6208
6209
6210     /* Host: One message in queue */
6211     IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
6212     check( 1, dwCount );
6213     dwDataSize = 1024;
6214     hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, DPRECEIVE_PEEK,
6215                                lpData, &dwDataSize );
6216     checkHR( DP_OK, hr );
6217     checkConv( DPSYS_CREATEPLAYERORGROUP, lpData->dwType, dpMsgType2str );
6218
6219     /* Peer: No messages */
6220     IDirectPlayX_GetMessageCount( pDP[1], dpid[1], &dwCount );
6221     check( 0, dwCount );
6222     hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, DPRECEIVE_PEEK,
6223                                lpData, &dwDataSize );
6224     checkHR( DPERR_NOMESSAGES, hr );
6225
6226
6227     /* Closing host */
6228     IDirectPlayX_Close( pDP[0] );
6229
6230
6231     /* Host: Queue is cleaned */
6232     IDirectPlayX_GetMessageCount( pDP[0], dpid[0], &dwCount );
6233     check( 0, dwCount );
6234     hr = IDirectPlayX_Receive( pDP[0], &idFrom, &idTo, DPRECEIVE_PEEK,
6235                                lpData, &dwDataSize );
6236     checkHR( DPERR_NOMESSAGES, hr );
6237
6238     /* Peer: gets message of player destruction */
6239     IDirectPlayX_GetMessageCount( pDP[1], dpid[1], &dwCount );
6240     check( 2, dwCount );
6241     dwDataSize = 1024;
6242     hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, DPRECEIVE_PEEK,
6243                                lpData, &dwDataSize );
6244     checkHR( DP_OK, hr );
6245     checkConv( DPSYS_DESTROYPLAYERORGROUP, lpData->dwType, dpMsgType2str );
6246
6247
6248     /* Message analysis */
6249     for (i=0; i<2; i++)
6250     {
6251         hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, 0,
6252                                    lpData, &dwDataSize );
6253         checkHR( DP_OK, hr );
6254         check( DPID_SYSMSG, idFrom );
6255         check( dpid[1], idTo ); /* Peer player id */
6256         switch(i)
6257         {
6258         case 0:
6259             checkConv( DPSYS_DESTROYPLAYERORGROUP, lpData->dwType,
6260                        dpMsgType2str );
6261             check( DPPLAYERTYPE_PLAYER, lpData->dwPlayerType );
6262             check( dpid[0],             lpData->dpId ); /* Host player id */
6263             checkLP( NULL,              lpData->lpLocalData );
6264             check( 0,                   lpData->dwLocalDataSize );
6265             checkLP( NULL,              lpData->lpRemoteData );
6266             check( 0,                   lpData->dwRemoteDataSize );
6267             checkLP( NULL,              U1(lpData->dpnName).lpszShortNameA );
6268             check( 0,                   lpData->dpIdParent );
6269             checkFlags( 0,              lpData->dwFlags,
6270                         FLAGS_DPPLAYER | FLAGS_DPGROUP );
6271             break;
6272         case 1:
6273             checkConv( DPSYS_HOST, lpData->dwType, dpMsgType2str );
6274             break;
6275         default:
6276             break;
6277         }
6278         dwDataSize = 1024;
6279     }
6280     hr = IDirectPlayX_Receive( pDP[1], &idFrom, &idTo, 0, lpData, &dwDataSize );
6281     checkHR( DPERR_NOMESSAGES, hr );
6282
6283
6284     HeapFree( GetProcessHeap(), 0, lpData );
6285     IDirectPlayX_Release( pDP[0] );
6286     IDirectPlayX_Release( pDP[1] );
6287
6288 }
6289
6290
6291 START_TEST(dplayx)
6292 {
6293     if (!winetest_interactive)
6294     {
6295         skip("Run in interactive mode to run dplayx tests.\n");
6296         return;
6297     }
6298
6299     CoInitialize( NULL );
6300
6301     trace("Running in interactive mode, tests will take a while\n");
6302
6303     test_DirectPlayCreate();
6304     test_EnumConnections();
6305     test_InitializeConnection();
6306
6307     test_GetCaps();
6308     /* test_Open() takes almost a minute, */
6309     test_Open();
6310     /* test_EnumSession takes three minutes */
6311     test_EnumSessions();
6312     test_SessionDesc();
6313
6314     /* test_CreatePlayer() takes over a minute */
6315     test_CreatePlayer();
6316     test_GetPlayerCaps();
6317     test_PlayerData();
6318     test_PlayerName();
6319
6320     /* test_GetPlayerAccount() takes over 30s */
6321     test_GetPlayerAccount();
6322     test_GetPlayerAddress();
6323     test_GetPlayerFlags();
6324
6325     test_CreateGroup();
6326     test_GroupOwner();
6327
6328     test_EnumPlayers();
6329     test_EnumGroups();
6330     test_EnumGroupsInGroup();
6331
6332     test_groups_p2p();
6333     test_groups_cs();
6334
6335     test_Send();
6336     test_Receive();
6337     test_GetMessageCount();
6338     test_GetMessageQueue();
6339
6340     test_remote_data_replication();
6341     test_host_migration();
6342
6343     CoUninitialize();
6344 }