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