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