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