~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/dplayx/tests/dplayx.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /* DirectPlay Conformance Tests
  2  *
  3  * Copyright 2007 - Alessandro Pignotti
  4  *
  5  * This library is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU Lesser General Public
  7  * License as published by the Free Software Foundation; either
  8  * version 2.1 of the License, or (at your option) any later version.
  9  *
 10  * This library is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public
 16  * License along with this library; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 18  */
 19 
 20 #include "wine/test.h"
 21 #include <stdio.h>
 22 #define INITGUID
 23 #include <dplay.h>
 24 #include <dplobby.h>
 25 
 26 
 27 #define check(expected, result)                 \
 28     ok( (expected) == (result),                 \
 29         "expected=%d got=%d\n",                 \
 30         (int)(expected), (int)(result) );
 31 #define checkLP(expected, result)               \
 32     ok( (expected) == (result),                 \
 33         "expected=%p got=%p\n",                 \
 34         expected, result );
 35 #define checkHR(expected, result)                       \
 36     ok( (expected) == (result),                         \
 37         "expected=%s got=%s\n",                         \
 38         dpResult2str(expected), dpResult2str(result) );
 39 #define checkStr(expected, result)                              \
 40     ok( (result != NULL) && (!strcmp(expected, result)),        \
 41         "expected=%s got=%s\n",                                 \
 42         expected, result );
 43 #define checkFlags(expected, result, flags)     \
 44     ok( (expected) == (result),                 \
 45         "expected=0x%08x(%s) got=0x%08x(%s)\n", \
 46         expected, dwFlags2str(expected, flags), \
 47         result, dwFlags2str(result, flags) );
 48 #define checkGuid(expected, result)             \
 49     ok( IsEqualGUID(expected, result),          \
 50         "expected=%s got=%s\n",                 \
 51         Guid2str(expected), Guid2str(result) );
 52 #define checkConv(expected, result, function)   \
 53     ok( (expected) == (result),                 \
 54         "expected=0x%08x(%s) got=0x%08x(%s)\n", \
 55         expected, function(expected),           \
 56         result, function(result) );
 57 
 58 
 59 DEFINE_GUID(appGuid, 0xbdcfe03e, 0xf0ec, 0x415b, 0x82, 0x11, 0x6f, 0x86, 0xd8, 0x19, 0x7f, 0xe1);
 60 DEFINE_GUID(appGuid2, 0x93417d3f, 0x7d26, 0x46ba, 0xb5, 0x76, 0xfe, 0x4b, 0x20, 0xbb, 0xad, 0x70);
 61 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 62 
 63 
 64 typedef struct tagCallbackData
 65 {
 66     LPDIRECTPLAY4 pDP;
 67     UINT dwCounter1, dwCounter2;
 68     DWORD dwFlags;
 69     char szTrace1[1024], szTrace2[1024];
 70     DPID *dpid;
 71     UINT dpidSize;
 72 } CallbackData, *lpCallbackData;
 73 
 74 
 75 static LPSTR get_temp_buffer(void)
 76 {
 77     static UINT index = 0;
 78     static char buff[10][256];
 79 
 80     index = (index + 1) % 10;
 81     *buff[index] = 0;
 82 
 83     return buff[index];
 84 }
 85 
 86 
 87 static LPCSTR Guid2str(const GUID *guid)
 88 {
 89     LPSTR buffer = get_temp_buffer();
 90 
 91     if (!guid) return "(null)";
 92 
 93     /* Service providers */
 94     if (IsEqualGUID(guid, &DPSPGUID_IPX))
 95         return "DPSPGUID_IPX";
 96     if (IsEqualGUID(guid, &DPSPGUID_TCPIP))
 97         return "DPSPGUID_TCPIP";
 98     if (IsEqualGUID(guid, &DPSPGUID_SERIAL))
 99         return "DPSPGUID_SERIAL";
100     if (IsEqualGUID(guid, &DPSPGUID_MODEM))
101         return "DPSPGUID_MODEM";
102     /* DirectPlay Address ID's */
103     if (IsEqualGUID(guid, &DPAID_TotalSize))
104         return "DPAID_TotalSize";
105     if (IsEqualGUID(guid, &DPAID_ServiceProvider))
106         return "DPAID_ServiceProvider";
107     if (IsEqualGUID(guid, &DPAID_LobbyProvider))
108         return "DPAID_LobbyProvider";
109     if (IsEqualGUID(guid, &DPAID_Phone))
110         return "DPAID_Phone";
111     if (IsEqualGUID(guid, &DPAID_PhoneW))
112         return "DPAID_PhoneW";
113     if (IsEqualGUID(guid, &DPAID_Modem))
114         return "DPAID_Modem";
115     if (IsEqualGUID(guid, &DPAID_ModemW))
116         return "DPAID_ModemW";
117     if (IsEqualGUID(guid, &DPAID_INet))
118         return "DPAID_INet";
119     if (IsEqualGUID(guid, &DPAID_INetW))
120         return "DPAID_INetW";
121     if (IsEqualGUID(guid, &DPAID_INetPort))
122         return "DPAID_INetPort";
123     if (IsEqualGUID(guid, &DPAID_ComPort))
124         return "DPAID_ComPort";
125 
126     sprintf( buffer, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
127              guid->Data1, guid->Data2, guid->Data3,
128              guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
129              guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
130     return buffer;
131 
132 }
133 
134 
135 static LPCSTR dpResult2str(HRESULT hr)
136 {
137     switch (hr)
138     {
139     case DP_OK:                          return "DP_OK";
140     case DPERR_ALREADYINITIALIZED:       return "DPERR_ALREADYINITIALIZED";
141     case DPERR_ACCESSDENIED:             return "DPERR_ACCESSDENIED";
142     case DPERR_ACTIVEPLAYERS:            return "DPERR_ACTIVEPLAYERS";
143     case DPERR_BUFFERTOOSMALL:           return "DPERR_BUFFERTOOSMALL";
144     case DPERR_CANTADDPLAYER:            return "DPERR_CANTADDPLAYER";
145     case DPERR_CANTCREATEGROUP:          return "DPERR_CANTCREATEGROUP";
146     case DPERR_CANTCREATEPLAYER:         return "DPERR_CANTCREATEPLAYER";
147     case DPERR_CANTCREATESESSION:        return "DPERR_CANTCREATESESSION";
148     case DPERR_CAPSNOTAVAILABLEYET:      return "DPERR_CAPSNOTAVAILABLEYET";
149     case DPERR_EXCEPTION:                return "DPERR_EXCEPTION";
150     case DPERR_GENERIC:                  return "DPERR_GENERIC";
151     case DPERR_INVALIDFLAGS:             return "DPERR_INVALIDFLAGS";
152     case DPERR_INVALIDOBJECT:            return "DPERR_INVALIDOBJECT";
153     case DPERR_INVALIDPARAMS:            return "DPERR_INVALIDPARAMS";
154         /*           symbol with the same value: DPERR_INVALIDPARAM */
155     case DPERR_INVALIDPLAYER:            return "DPERR_INVALIDPLAYER";
156     case DPERR_INVALIDGROUP:             return "DPERR_INVALIDGROUP";
157     case DPERR_NOCAPS:                   return "DPERR_NOCAPS";
158     case DPERR_NOCONNECTION:             return "DPERR_NOCONNECTION";
159     case DPERR_NOMEMORY:                 return "DPERR_NOMEMORY";
160         /*           symbol with the same value: DPERR_OUTOFMEMORY */
161     case DPERR_NOMESSAGES:               return "DPERR_NOMESSAGES";
162     case DPERR_NONAMESERVERFOUND:        return "DPERR_NONAMESERVERFOUND";
163     case DPERR_NOPLAYERS:                return "DPERR_NOPLAYERS";
164     case DPERR_NOSESSIONS:               return "DPERR_NOSESSIONS";
165     case DPERR_PENDING:                  return "DPERR_PENDING";
166     case DPERR_SENDTOOBIG:               return "DPERR_SENDTOOBIG";
167     case DPERR_TIMEOUT:                  return "DPERR_TIMEOUT";
168     case DPERR_UNAVAILABLE:              return "DPERR_UNAVAILABLE";
169     case DPERR_UNSUPPORTED:              return "DPERR_UNSUPPORTED";
170     case DPERR_BUSY:                     return "DPERR_BUSY";
171     case DPERR_USERCANCEL:               return "DPERR_USERCANCEL";
172     case DPERR_NOINTERFACE:              return "DPERR_NOINTERFACE";
173     case DPERR_CANNOTCREATESERVER:       return "DPERR_CANNOTCREATESERVER";
174     case DPERR_PLAYERLOST:               return "DPERR_PLAYERLOST";
175     case DPERR_SESSIONLOST:              return "DPERR_SESSIONLOST";
176     case DPERR_UNINITIALIZED:            return "DPERR_UNINITIALIZED";
177     case DPERR_NONEWPLAYERS:             return "DPERR_NONEWPLAYERS";
178     case DPERR_INVALIDPASSWORD:          return "DPERR_INVALIDPASSWORD";
179     case DPERR_CONNECTING:               return "DPERR_CONNECTING";
180     case DPERR_CONNECTIONLOST:           return "DPERR_CONNECTIONLOST";
181     case DPERR_UNKNOWNMESSAGE:           return "DPERR_UNKNOWNMESSAGE";
182     case DPERR_CANCELFAILED:             return "DPERR_CANCELFAILED";
183     case DPERR_INVALIDPRIORITY:          return "DPERR_INVALIDPRIORITY";
184     case DPERR_NOTHANDLED:               return "DPERR_NOTHANDLED";
185     case DPERR_CANCELLED:                return "DPERR_CANCELLED";
186     case DPERR_ABORTED:                  return "DPERR_ABORTED";
187     case DPERR_BUFFERTOOLARGE:           return "DPERR_BUFFERTOOLARGE";
188     case DPERR_CANTCREATEPROCESS:        return "DPERR_CANTCREATEPROCESS";
189     case DPERR_APPNOTSTARTED:            return "DPERR_APPNOTSTARTED";
190     case DPERR_INVALIDINTERFACE:         return "DPERR_INVALIDINTERFACE";
191     case DPERR_NOSERVICEPROVIDER:        return "DPERR_NOSERVICEPROVIDER";
192     case DPERR_UNKNOWNAPPLICATION:       return "DPERR_UNKNOWNAPPLICATION";
193     case DPERR_NOTLOBBIED:               return "DPERR_NOTLOBBIED";
194     case DPERR_SERVICEPROVIDERLOADED:    return "DPERR_SERVICEPROVIDERLOADED";
195     case DPERR_ALREADYREGISTERED:        return "DPERR_ALREADYREGISTERED";
196     case DPERR_NOTREGISTERED:            return "DPERR_NOTREGISTERED";
197     case DPERR_AUTHENTICATIONFAILED:     return "DPERR_AUTHENTICATIONFAILED";
198     case DPERR_CANTLOADSSPI:             return "DPERR_CANTLOADSSPI";
199     case DPERR_ENCRYPTIONFAILED:         return "DPERR_ENCRYPTIONFAILED";
200     case DPERR_SIGNFAILED:               return "DPERR_SIGNFAILED";
201     case DPERR_CANTLOADSECURITYPACKAGE:  return "DPERR_CANTLOADSECURITYPACKAGE";
202     case DPERR_ENCRYPTIONNOTSUPPORTED:   return "DPERR_ENCRYPTIONNOTSUPPORTED";
203     case DPERR_CANTLOADCAPI:             return "DPERR_CANTLOADCAPI";
204     case DPERR_NOTLOGGEDIN:              return "DPERR_NOTLOGGEDIN";
205     case DPERR_LOGONDENIED:              return "DPERR_LOGONDENIED";
206     case CLASS_E_NOAGGREGATION:          return "CLASS_E_NOAGGREGATION";
207 
208     default:
209     {
210         LPSTR buffer = get_temp_buffer();
211         sprintf( buffer, "%d", HRESULT_CODE(hr) );
212         return buffer;
213     }
214     }
215 }
216 
217 static LPCSTR dpMsgType2str(DWORD dwType)
218 {
219     switch(dwType)
220     {
221     case DPSYS_CREATEPLAYERORGROUP:      return "DPSYS_CREATEPLAYERORGROUP";
222     case DPSYS_DESTROYPLAYERORGROUP:     return "DPSYS_DESTROYPLAYERORGROUP";
223     case DPSYS_ADDPLAYERTOGROUP:         return "DPSYS_ADDPLAYERTOGROUP";
224     case DPSYS_DELETEPLAYERFROMGROUP:    return "DPSYS_DELETEPLAYERFROMGROUP";
225     case DPSYS_SESSIONLOST:              return "DPSYS_SESSIONLOST";
226     case DPSYS_HOST:                     return "DPSYS_HOST";
227     case DPSYS_SETPLAYERORGROUPDATA:     return "DPSYS_SETPLAYERORGROUPDATA";
228     case DPSYS_SETPLAYERORGROUPNAME:     return "DPSYS_SETPLAYERORGROUPNAME";
229     case DPSYS_SETSESSIONDESC:           return "DPSYS_SETSESSIONDESC";
230     case DPSYS_ADDGROUPTOGROUP:          return "DPSYS_ADDGROUPTOGROUP";
231     case DPSYS_DELETEGROUPFROMGROUP:     return "DPSYS_DELETEGROUPFROMGROUP";
232     case DPSYS_SECUREMESSAGE:            return "DPSYS_SECUREMESSAGE";
233     case DPSYS_STARTSESSION:             return "DPSYS_STARTSESSION";
234     case DPSYS_CHAT:                     return "DPSYS_DPSYS_CHAT";
235     case DPSYS_SETGROUPOWNER:            return "DPSYS_SETGROUPOWNER";
236     case DPSYS_SENDCOMPLETE:             return "DPSYS_SENDCOMPLETE";
237 
238     default:                             return "UNKNOWN";
239     }
240 }
241 
242 static LPCSTR dwFlags2str(DWORD dwFlags, DWORD flagType)
243 {
244 
245 #define FLAGS_DPCONNECTION     (1<<0)
246 #define FLAGS_DPENUMPLAYERS    (1<<1)
247 #define FLAGS_DPENUMGROUPS     (1<<2)
248 #define FLAGS_DPPLAYER         (1<<3)
249 #define FLAGS_DPGROUP          (1<<4)
250 #define FLAGS_DPENUMSESSIONS   (1<<5)
251 #define FLAGS_DPGETCAPS        (1<<6)
252 #define FLAGS_DPGET            (1<<7)
253 #define FLAGS_DPRECEIVE        (1<<8)
254 #define FLAGS_DPSEND           (1<<9)
255 #define FLAGS_DPSET            (1<<10)
256 #define FLAGS_DPMESSAGEQUEUE   (1<<11)
257 #define FLAGS_DPCONNECT        (1<<12)
258 #define FLAGS_DPOPEN           (1<<13)
259 #define FLAGS_DPSESSION        (1<<14)
260 #define FLAGS_DPLCONNECTION    (1<<15)
261 #define FLAGS_DPESC            (1<<16)
262 #define FLAGS_DPCAPS           (1<<17)
263 
264     LPSTR flags = get_temp_buffer();
265 
266     /* EnumConnections */
267 
268     if (flagType & FLAGS_DPCONNECTION)
269     {
270         if (dwFlags & DPCONNECTION_DIRECTPLAY)
271             strcat(flags, "DPCONNECTION_DIRECTPLAY,");
272         if (dwFlags & DPCONNECTION_DIRECTPLAYLOBBY)
273             strcat(flags, "DPCONNECTION_DIRECTPLAYLOBBY,");
274     }
275 
276     /* EnumPlayers,
277        EnumGroups */
278 
279     if (flagType & FLAGS_DPENUMPLAYERS)
280     {
281         if (dwFlags == DPENUMPLAYERS_ALL)
282             strcat(flags, "DPENUMPLAYERS_ALL,");
283         if (dwFlags & DPENUMPLAYERS_LOCAL)
284             strcat(flags, "DPENUMPLAYERS_LOCAL,");
285         if (dwFlags & DPENUMPLAYERS_REMOTE)
286             strcat(flags, "DPENUMPLAYERS_REMOTE,");
287         if (dwFlags & DPENUMPLAYERS_GROUP)
288             strcat(flags, "DPENUMPLAYERS_GROUP,");
289         if (dwFlags & DPENUMPLAYERS_SESSION)
290             strcat(flags, "DPENUMPLAYERS_SESSION,");
291         if (dwFlags & DPENUMPLAYERS_SERVERPLAYER)
292             strcat(flags, "DPENUMPLAYERS_SERVERPLAYER,");
293         if (dwFlags & DPENUMPLAYERS_SPECTATOR)
294             strcat(flags, "DPENUMPLAYERS_SPECTATOR,");
295         if (dwFlags & DPENUMPLAYERS_OWNER)
296             strcat(flags, "DPENUMPLAYERS_OWNER,");
297     }
298     if (flagType & FLAGS_DPENUMGROUPS)
299     {
300         if (dwFlags == DPENUMGROUPS_ALL)
301             strcat(flags, "DPENUMGROUPS_ALL,");
302         if (dwFlags & DPENUMPLAYERS_LOCAL)
303             strcat(flags, "DPENUMGROUPS_LOCAL,");
304         if (dwFlags & DPENUMPLAYERS_REMOTE)
305             strcat(flags, "DPENUMGROUPS_REMOTE,");
306         if (dwFlags & DPENUMPLAYERS_GROUP)
307             strcat(flags, "DPENUMGROUPS_GROUP,");
308         if (dwFlags & DPENUMPLAYERS_SESSION)
309             strcat(flags, "DPENUMGROUPS_SESSION,");
310         if (dwFlags & DPENUMGROUPS_SHORTCUT)
311             strcat(flags, "DPENUMGROUPS_SHORTCUT,");
312         if (dwFlags & DPENUMGROUPS_STAGINGAREA)
313             strcat(flags, "DPENUMGROUPS_STAGINGAREA,");
314         if (dwFlags & DPENUMGROUPS_HIDDEN)
315             strcat(flags, "DPENUMGROUPS_HIDDEN,");
316     }
317 
318     /* CreatePlayer */
319 
320     if (flagType & FLAGS_DPPLAYER)
321     {
322         if (dwFlags & DPPLAYER_SERVERPLAYER)
323             strcat(flags, "DPPLAYER_SERVERPLAYER,");
324         if (dwFlags & DPPLAYER_SPECTATOR)
325             strcat(flags, "DPPLAYER_SPECTATOR,");
326         if (dwFlags & DPPLAYER_LOCAL)
327             strcat(flags, "DPPLAYER_LOCAL,");
328         if (dwFlags & DPPLAYER_OWNER)
329             strcat(flags, "DPPLAYER_OWNER,");
330     }
331 
332     /* CreateGroup */
333 
334     if (flagType & FLAGS_DPGROUP)
335     {
336         if (dwFlags & DPGROUP_STAGINGAREA)
337             strcat(flags, "DPGROUP_STAGINGAREA,");
338         if (dwFlags & DPGROUP_LOCAL)
339             strcat(flags, "DPGROUP_LOCAL,");
340         if (dwFlags & DPGROUP_HIDDEN)
341             strcat(flags, "DPGROUP_HIDDEN,");
342     }
343 
344     /* EnumSessions */
345 
346     if (flagType & FLAGS_DPENUMSESSIONS)
347     {
348         if (dwFlags & DPENUMSESSIONS_AVAILABLE)
349             strcat(flags, "DPENUMSESSIONS_AVAILABLE,");
350         if (dwFlags &  DPENUMSESSIONS_ALL)
351             strcat(flags, "DPENUMSESSIONS_ALL,");
352         if (dwFlags & DPENUMSESSIONS_ASYNC)
353             strcat(flags, "DPENUMSESSIONS_ASYNC,");
354         if (dwFlags & DPENUMSESSIONS_STOPASYNC)
355             strcat(flags, "DPENUMSESSIONS_STOPASYNC,");
356         if (dwFlags & DPENUMSESSIONS_PASSWORDREQUIRED)
357             strcat(flags, "DPENUMSESSIONS_PASSWORDREQUIRED,");
358         if (dwFlags & DPENUMSESSIONS_RETURNSTATUS)
359             strcat(flags, "DPENUMSESSIONS_RETURNSTATUS,");
360     }
361 
362     /* GetCaps,
363        GetPlayerCaps */
364 
365     if (flagType & FLAGS_DPGETCAPS)
366     {
367         if (dwFlags & DPGETCAPS_GUARANTEED)
368             strcat(flags, "DPGETCAPS_GUARANTEED,");
369     }
370 
371     /* GetGroupData,
372        GetPlayerData */
373 
374     if (flagType & FLAGS_DPGET)
375     {
376         if (dwFlags == DPGET_REMOTE)
377             strcat(flags, "DPGET_REMOTE,");
378         if (dwFlags & DPGET_LOCAL)
379             strcat(flags, "DPGET_LOCAL,");
380     }
381 
382     /* Receive */
383 
384     if (flagType & FLAGS_DPRECEIVE)
385     {
386         if (dwFlags & DPRECEIVE_ALL)
387             strcat(flags, "DPRECEIVE_ALL,");
388         if (dwFlags & DPRECEIVE_TOPLAYER)
389             strcat(flags, "DPRECEIVE_TOPLAYER,");
390         if (dwFlags & DPRECEIVE_FROMPLAYER)
391             strcat(flags, "DPRECEIVE_FROMPLAYER,");
392         if (dwFlags & DPRECEIVE_PEEK)
393             strcat(flags, "DPRECEIVE_PEEK,");
394     }
395 
396     /* Send */
397 
398     if (flagType & FLAGS_DPSEND)
399     {
400         /*if (dwFlags == DPSEND_NONGUARANTEED)
401           strcat(flags, "DPSEND_NONGUARANTEED,");*/
402         if (dwFlags == DPSEND_MAX_PRIORITY) /* = DPSEND_MAX_PRI */
403         {
404             strcat(flags, "DPSEND_MAX_PRIORITY,");
405         }
406         else
407         {
408             if (dwFlags & DPSEND_GUARANTEED)
409                 strcat(flags, "DPSEND_GUARANTEED,");
410             if (dwFlags & DPSEND_HIGHPRIORITY)
411                 strcat(flags, "DPSEND_HIGHPRIORITY,");
412             if (dwFlags & DPSEND_OPENSTREAM)
413                 strcat(flags, "DPSEND_OPENSTREAM,");
414             if (dwFlags & DPSEND_CLOSESTREAM)
415                 strcat(flags, "DPSEND_CLOSESTREAM,");
416             if (dwFlags & DPSEND_SIGNED)
417                 strcat(flags, "DPSEND_SIGNED,");
418             if (dwFlags & DPSEND_ENCRYPTED)
419                 strcat(flags, "DPSEND_ENCRYPTED,");
420             if (dwFlags & DPSEND_LOBBYSYSTEMMESSAGE)
421                 strcat(flags, "DPSEND_LOBBYSYSTEMMESSAGE,");
422             if (dwFlags & DPSEND_ASYNC)
423                 strcat(flags, "DPSEND_ASYNC,");
424             if (dwFlags & DPSEND_NOSENDCOMPLETEMSG)
425                 strcat(flags, "DPSEND_NOSENDCOMPLETEMSG,");
426         }
427     }
428 
429     /* SetGroupData,
430        SetGroupName,
431        SetPlayerData,
432        SetPlayerName,
433        SetSessionDesc */
434 
435     if (flagType & FLAGS_DPSET)
436     {
437         if (dwFlags == DPSET_REMOTE)
438             strcat(flags, "DPSET_REMOTE,");
439         if (dwFlags & DPSET_LOCAL)
440             strcat(flags, "DPSET_LOCAL,");
441         if (dwFlags & DPSET_GUARANTEED)
442             strcat(flags, "DPSET_GUARANTEED,");
443     }
444 
445     /* GetMessageQueue */
446 
447     if (flagType & FLAGS_DPMESSAGEQUEUE)
448     {
449         if (dwFlags & DPMESSAGEQUEUE_SEND)
450             strcat(flags, "DPMESSAGEQUEUE_SEND,");
451         if (dwFlags & DPMESSAGEQUEUE_RECEIVE)
452             strcat(flags, "DPMESSAGEQUEUE_RECEIVE,");
453     }
454 
455     /* Connect */
456 
457     if (flagType & FLAGS_DPCONNECT)
458     {
459         if (dwFlags & DPCONNECT_RETURNSTATUS)
460             strcat(flags, "DPCONNECT_RETURNSTATUS,");
461     }
462 
463     /* Open */
464 
465     if (flagType & FLAGS_DPOPEN)
466     {
467         if (dwFlags & DPOPEN_JOIN)
468             strcat(flags, "DPOPEN_JOIN,");
469         if (dwFlags & DPOPEN_CREATE)
470             strcat(flags, "DPOPEN_CREATE,");
471         if (dwFlags & DPOPEN_RETURNSTATUS)
472             strcat(flags, "DPOPEN_RETURNSTATUS,");
473     }
474 
475     /* DPSESSIONDESC2 */
476 
477     if (flagType & FLAGS_DPSESSION)
478     {
479         if (dwFlags & DPSESSION_NEWPLAYERSDISABLED)
480             strcat(flags, "DPSESSION_NEWPLAYERSDISABLED,");
481         if (dwFlags & DPSESSION_MIGRATEHOST)
482             strcat(flags, "DPSESSION_MIGRATEHOST,");
483         if (dwFlags & DPSESSION_NOMESSAGEID)
484             strcat(flags, "DPSESSION_NOMESSAGEID,");
485         if (dwFlags & DPSESSION_JOINDISABLED)
486             strcat(flags, "DPSESSION_JOINDISABLED,");
487         if (dwFlags & DPSESSION_KEEPALIVE)
488             strcat(flags, "DPSESSION_KEEPALIVE,");
489         if (dwFlags & DPSESSION_NODATAMESSAGES)
490             strcat(flags, "DPSESSION_NODATAMESSAGES,");
491         if (dwFlags & DPSESSION_SECURESERVER)
492             strcat(flags, "DPSESSION_SECURESERVER,");
493         if (dwFlags & DPSESSION_PRIVATE)
494             strcat(flags, "DPSESSION_PRIVATE,");
495         if (dwFlags & DPSESSION_PASSWORDREQUIRED)
496             strcat(flags, "DPSESSION_PASSWORDREQUIRED,");
497         if (dwFlags & DPSESSION_MULTICASTSERVER)
498             strcat(flags, "DPSESSION_MULTICASTSERVER,");
499         if (dwFlags & DPSESSION_CLIENTSERVER)
500             strcat(flags, "DPSESSION_CLIENTSERVER,");
501 
502         if (dwFlags & DPSESSION_DIRECTPLAYPROTOCOL)
503             strcat(flags, "DPSESSION_DIRECTPLAYPROTOCOL,");
504         if (dwFlags & DPSESSION_NOPRESERVEORDER)
505             strcat(flags, "DPSESSION_NOPRESERVEORDER,");
506         if (dwFlags & DPSESSION_OPTIMIZELATENCY)
507             strcat(flags, "DPSESSION_OPTIMIZELATENCY,");
508 
509     }
510 
511     /* DPLCONNECTION */
512 
513     if (flagType & FLAGS_DPLCONNECTION)
514     {
515         if (dwFlags & DPLCONNECTION_CREATESESSION)
516             strcat(flags, "DPLCONNECTION_CREATESESSION,");
517         if (dwFlags & DPLCONNECTION_JOINSESSION)
518             strcat(flags, "DPLCONNECTION_JOINSESSION,");
519     }
520 
521     /* EnumSessionsCallback2 */
522 
523     if (flagType & FLAGS_DPESC)
524     {
525         if (dwFlags & DPESC_TIMEDOUT)
526             strcat(flags, "DPESC_TIMEDOUT,");
527     }
528 
529     /* GetCaps,
530        GetPlayerCaps */
531 
532     if (flagType & FLAGS_DPCAPS)
533     {
534         if (dwFlags & DPCAPS_ISHOST)
535             strcat(flags, "DPCAPS_ISHOST,");
536         if (dwFlags & DPCAPS_GROUPOPTIMIZED)
537             strcat(flags, "DPCAPS_GROUPOPTIMIZED,");
538         if (dwFlags & DPCAPS_KEEPALIVEOPTIMIZED)
539             strcat(flags, "DPCAPS_KEEPALIVEOPTIMIZED,");
540         if (dwFlags & DPCAPS_GUARANTEEDOPTIMIZED)
541             strcat(flags, "DPCAPS_GUARANTEEDOPTIMIZED,");
542         if (dwFlags & DPCAPS_GUARANTEEDSUPPORTED)
543             strcat(flags, "DPCAPS_GUARANTEEDSUPPORTED,");
544         if (dwFlags & DPCAPS_SIGNINGSUPPORTED)
545             strcat(flags, "DPCAPS_SIGNINGSUPPORTED,");
546         if (dwFlags & DPCAPS_ENCRYPTIONSUPPORTED)
547             strcat(flags, "DPCAPS_ENCRYPTIONSUPPORTED,");
548         if (dwFlags & DPCAPS_ASYNCCANCELSUPPORTED)
549             strcat(flags, "DPCAPS_ASYNCCANCELSUPPORTED,");
550         if (dwFlags & DPCAPS_ASYNCCANCELALLSUPPORTED)
551             strcat(flags, "DPCAPS_ASYNCCANCELALLSUPPORTED,");
552         if (dwFlags & DPCAPS_SENDTIMEOUTSUPPORTED)
553             strcat(flags, "DPCAPS_SENDTIMEOUTSUPPORTED,");
554         if (dwFlags & DPCAPS_SENDPRIORITYSUPPORTED)
555             strcat(flags, "DPCAPS_SENDPRIORITYSUPPORTED,");
556         if (dwFlags & DPCAPS_ASYNCSUPPORTED)
557             strcat(flags, "DPCAPS_ASYNCSUPPORTED,");
558 
559         if (dwFlags & DPPLAYERCAPS_LOCAL)
560             strcat(flags, "DPPLAYERCAPS_LOCAL,");
561     }
562 
563     if ((strlen(flags) == 0) && (dwFlags != 0))
564         strcpy(flags, "UNKNOWN");
565     else
566         flags[strlen(flags)-1] = '\0';
567 
568     return flags;
569 }
570 
571 static char dpid2char(DPID* dpid, DWORD dpidSize, DPID idPlayer)
572 {
573     UINT i;
574     if ( idPlayer == DPID_SYSMSG )
575         return 'S';
576     for (i=0; i<dpidSize; i++)
577     {
578         if ( idPlayer == dpid[i] )
579             return (char)(i+48);
580     }
581     return '?';
582 }
583 
584 static void check_messages( LPDIRECTPLAY4 pDP,
585                             DPID *dpid,
586                             DWORD dpidSize,
587                             lpCallbackData callbackData )
588 {
589     /* Retrieves all messages from the queue of pDP, performing tests
590      * to check if we are receiving what we expect.
591      *
592      * Information about the messages is stores in callbackData:
593      *
594      * callbackData->dwCounter1: Number of messages received.
595      * callbackData->szTrace1: Traces for sender and receiver.
596      *     We store the position a dpid holds in the dpid array.
597      *     Example:
598      *
599      *       trace string: "01,02,03,14"
600      *           expanded: [ '01', '02', '03', '14' ]
601      *                         \     \     \     \
602      *                          \     \     \     ) message 3: from 1 to 4
603      *                           \     \     ) message 2: from 0 to 3
604      *                            \     ) message 1: from 0 to 2
605      *                             ) message 0: from 0 to 1
606      *
607      *     In general terms:
608      *       sender of message i   = character in place 3*i of the array
609      *       receiver of message i = character in place 3*i+1 of the array
610      *
611      *     A sender value of 'S' means DPID_SYSMSG, this is, a system message.
612      *
613      * callbackData->szTrace2: Traces for message sizes.
614      */
615 
616     DPID idFrom, idTo;
617     UINT i;
618     DWORD dwDataSize = 1024;
619     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
620     HRESULT hr;
621     char temp[5];
622 
623     callbackData->szTrace2[0] = '\0';
624 
625     i = 0;
626     while ( DP_OK == (hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0,
627                                                  lpData, &dwDataSize )) )
628     {
629 
630         callbackData->szTrace1[ 3*i   ] = dpid2char( dpid, dpidSize, idFrom );
631         callbackData->szTrace1[ 3*i+1 ] = dpid2char( dpid, dpidSize, idTo );
632         callbackData->szTrace1[ 3*i+2 ] = ',';
633 
634         sprintf( temp, "%d,", dwDataSize );
635         strcat( callbackData->szTrace2, temp );
636 
637         dwDataSize = 1024;
638         ++i;
639     }
640 
641     checkHR( DPERR_NOMESSAGES, hr );
642 
643     callbackData->szTrace1[ 3*i ] = '\0';
644     callbackData->dwCounter1 = i;
645 
646 
647     HeapFree( GetProcessHeap(), 0, lpData );
648 }
649 
650 static void init_TCPIP_provider( LPDIRECTPLAY4 pDP,
651                                  LPCSTR strIPAddressString,
652                                  WORD port )
653 {
654 
655     DPCOMPOUNDADDRESSELEMENT addressElements[3];
656     LPVOID pAddress = NULL;
657     DWORD dwAddressSize = 0;
658     LPDIRECTPLAYLOBBY3 pDPL;
659     HRESULT hr;
660 
661     CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
662                       &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
663 
664     /* Service provider */
665     addressElements[0].guidDataType = DPAID_ServiceProvider;
666     addressElements[0].dwDataSize   = sizeof(GUID);
667     addressElements[0].lpData       = (LPVOID) &DPSPGUID_TCPIP;
668 
669     /* IP address string */
670     addressElements[1].guidDataType = DPAID_INet;
671     addressElements[1].dwDataSize   = lstrlen(strIPAddressString) + 1;
672     addressElements[1].lpData       = (LPVOID) strIPAddressString;
673 
674     /* Optional Port number */
675     if( port > 0 )
676     {
677         addressElements[2].guidDataType = DPAID_INetPort;
678         addressElements[2].dwDataSize   = sizeof(WORD);
679         addressElements[2].lpData       = &port;
680     }
681 
682 
683     hr = IDirectPlayLobby_CreateCompoundAddress( pDPL, addressElements, 2,
684                                                  NULL, &dwAddressSize );
685     checkHR( DPERR_BUFFERTOOSMALL, hr );
686 
687     if( hr == DPERR_BUFFERTOOSMALL )
688     {
689         pAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressSize );
690         hr = IDirectPlayLobby_CreateCompoundAddress( pDPL, addressElements, 2,
691                                                      pAddress, &dwAddressSize );
692         checkHR( DP_OK, hr );
693     }
694 
695     hr = IDirectPlayX_InitializeConnection( pDP, pAddress, 0 );
696     todo_wine checkHR( DP_OK, hr );
697 
698     HeapFree( GetProcessHeap(), 0, pAddress );
699 
700 }
701 
702 static BOOL CALLBACK EnumSessions_cb_join( LPCDPSESSIONDESC2 lpThisSD,
703                                            LPDWORD lpdwTimeOut,
704                                            DWORD dwFlags,
705                                            LPVOID lpContext )
706 {
707     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
708     DPSESSIONDESC2 dpsd;
709     HRESULT hr;
710 
711     if (dwFlags & DPESC_TIMEDOUT)
712     {
713         return FALSE;
714     }
715 
716     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
717     dpsd.dwSize = sizeof(DPSESSIONDESC2);
718     dpsd.guidApplication = appGuid;
719     dpsd.guidInstance = lpThisSD->guidInstance;
720 
721     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
722     checkHR( DP_OK, hr );
723 
724     return TRUE;
725 }
726 
727 
728 /* DirectPlayCreate */
729 
730 static void test_DirectPlayCreate(void)
731 {
732 
733     LPDIRECTPLAY pDP;
734     HRESULT hr;
735 
736     /* TODO: Check how it behaves with pUnk!=NULL */
737 
738     /* pDP==NULL */
739     hr = DirectPlayCreate( NULL, NULL, NULL );
740     checkHR( DPERR_INVALIDPARAMS, hr );
741     hr = DirectPlayCreate( (LPGUID) &GUID_NULL, NULL, NULL );
742     checkHR( DPERR_INVALIDPARAMS, hr );
743     hr = DirectPlayCreate( (LPGUID) &DPSPGUID_TCPIP, NULL, NULL );
744     checkHR( DPERR_INVALIDPARAMS, hr );
745 
746     /* pUnk==NULL, pDP!=NULL */
747     hr = DirectPlayCreate( NULL, &pDP, NULL );
748     checkHR( DPERR_INVALIDPARAMS, hr );
749     hr = DirectPlayCreate( (LPGUID) &GUID_NULL, &pDP, NULL );
750     checkHR( DP_OK, hr );
751     if ( hr == DP_OK )
752         IDirectPlayX_Release( pDP );
753     hr = DirectPlayCreate( (LPGUID) &DPSPGUID_TCPIP, &pDP, NULL );
754     todo_wine checkHR( DP_OK, hr );
755     if ( hr == DP_OK )
756         IDirectPlayX_Release( pDP );
757 
758 }
759 
760 /* EnumConnections */
761 
762 static BOOL CALLBACK EnumAddress_cb2( REFGUID guidDataType,
763                                       DWORD dwDataSize,
764                                       LPCVOID lpData,
765                                       LPVOID lpContext )
766 {
767     lpCallbackData callbackData = (lpCallbackData) lpContext;
768 
769     static REFGUID types[] = { &DPAID_TotalSize,
770                                &DPAID_ServiceProvider,
771                                &GUID_NULL };
772     static DWORD sizes[] = { 4, 16, 0  };
773     static REFGUID sps[] = { &DPSPGUID_SERIAL, &DPSPGUID_MODEM,
774                              &DPSPGUID_IPX, &DPSPGUID_TCPIP };
775 
776 
777     checkGuid( types[ callbackData->dwCounter2 ], guidDataType );
778     check( sizes[ callbackData->dwCounter2 ], dwDataSize );
779 
780     if ( IsEqualGUID( types[0], guidDataType ) )
781     {
782         todo_wine check( 80, *((LPDWORD) lpData) );
783     }
784     else if ( IsEqualGUID( types[1], guidDataType ) )
785     {
786         todo_wine checkGuid( sps[ callbackData->dwCounter1 ], lpData );
787     }
788 
789     callbackData->dwCounter2++;
790 
791     return TRUE;
792 }
793 
794 static BOOL CALLBACK EnumConnections_cb( LPCGUID lpguidSP,
795                                          LPVOID lpConnection,
796                                          DWORD dwConnectionSize,
797                                          LPCDPNAME lpName,
798                                          DWORD dwFlags,
799                                          LPVOID lpContext )
800 {
801 
802     lpCallbackData callbackData = (lpCallbackData) lpContext;
803     LPDIRECTPLAYLOBBY pDPL;
804 
805 
806     if (!callbackData->dwFlags)
807     {
808         callbackData->dwFlags = DPCONNECTION_DIRECTPLAY;
809     }
810 
811     checkFlags( callbackData->dwFlags, dwFlags, FLAGS_DPCONNECTION );
812 
813     /* Get info from lpConnection */
814     CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
815                       &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
816 
817     callbackData->dwCounter2 = 0;
818     IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb2, lpConnection,
819                                   dwConnectionSize, callbackData );
820     todo_wine check( 3, callbackData->dwCounter2 );
821 
822     callbackData->dwCounter1++;
823 
824     return TRUE;
825 }
826 
827 static void test_EnumConnections(void)
828 {
829 
830     LPDIRECTPLAY4 pDP;
831     CallbackData callbackData;
832     HRESULT hr;
833 
834 
835     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
836                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
837 
838 
839     callbackData.dwCounter1 = 0;
840     callbackData.dwFlags = 0;
841     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
842                                        &callbackData, callbackData.dwFlags );
843     checkHR( DP_OK, hr );
844     check( 4, callbackData.dwCounter1 );
845 
846     callbackData.dwCounter1 = 0;
847     callbackData.dwFlags = 0;
848     hr = IDirectPlayX_EnumConnections( pDP, NULL, EnumConnections_cb,
849                                        &callbackData, callbackData.dwFlags );
850     checkHR( DP_OK, hr );
851     check( 4, callbackData.dwCounter1 );
852 
853     callbackData.dwCounter1 = 0;
854     callbackData.dwFlags = 0;
855     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, NULL,
856                                        &callbackData, callbackData.dwFlags );
857     checkHR( DPERR_INVALIDPARAMS, hr );
858     check( 0, callbackData.dwCounter1 );
859 
860 
861     /* Flag tests */
862     callbackData.dwCounter1 = 0;
863     callbackData.dwFlags = DPCONNECTION_DIRECTPLAY;
864     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
865                                        &callbackData, callbackData.dwFlags );
866     checkHR( DP_OK, hr );
867     check( 4, callbackData.dwCounter1 );
868 
869     callbackData.dwCounter1 = 0;
870     callbackData.dwFlags = DPCONNECTION_DIRECTPLAYLOBBY;
871     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
872                                        &callbackData, callbackData.dwFlags );
873     checkHR( DP_OK, hr );
874     check( 0, callbackData.dwCounter1 );
875 
876     callbackData.dwCounter1 = 0;
877     callbackData.dwFlags = ( DPCONNECTION_DIRECTPLAY |
878                              DPCONNECTION_DIRECTPLAYLOBBY );
879     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
880                                        &callbackData, callbackData.dwFlags );
881     checkHR( DP_OK, hr );
882     check( 4, callbackData.dwCounter1 );
883 
884     callbackData.dwCounter1 = 0;
885     callbackData.dwFlags = ~( DPCONNECTION_DIRECTPLAY |
886                               DPCONNECTION_DIRECTPLAYLOBBY );
887     hr = IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb,
888                                        &callbackData, callbackData.dwFlags );
889     checkHR( DPERR_INVALIDFLAGS, hr );
890     check( 0, callbackData.dwCounter1 );
891 
892 
893     IDirectPlayX_Release( pDP );
894 }
895 
896 /* InitializeConnection */
897 
898 static BOOL CALLBACK EnumConnections_cb2( LPCGUID lpguidSP,
899                                           LPVOID lpConnection,
900                                           DWORD dwConnectionSize,
901                                           LPCDPNAME lpName,
902                                           DWORD dwFlags,
903                                           LPVOID lpContext )
904 {
905     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
906     HRESULT hr;
907 
908     /* Incorrect parameters */
909     hr = IDirectPlayX_InitializeConnection( pDP, NULL, 1 );
910     checkHR( DPERR_INVALIDPARAMS, hr );
911     hr = IDirectPlayX_InitializeConnection( pDP, lpConnection, 1 );
912     checkHR( DPERR_INVALIDFLAGS, hr );
913 
914     /* Normal operation.
915        We're only interested in ensuring that the TCP/IP provider works */
916 
917     if( IsEqualGUID(lpguidSP, &DPSPGUID_TCPIP) )
918     {
919         hr = IDirectPlayX_InitializeConnection( pDP, lpConnection, 0 );
920         todo_wine checkHR( DP_OK, hr );
921         hr = IDirectPlayX_InitializeConnection( pDP, lpConnection, 0 );
922         todo_wine checkHR( DPERR_ALREADYINITIALIZED, hr );
923     }
924 
925     return TRUE;
926 }
927 
928 static void test_InitializeConnection(void)
929 {
930 
931     LPDIRECTPLAY4 pDP;
932 
933     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
934                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
935 
936     IDirectPlayX_EnumConnections( pDP, &appGuid, EnumConnections_cb2, pDP, 0 );
937 
938     IDirectPlayX_Release( pDP );
939 }
940 
941 /* GetCaps */
942 
943 static void test_GetCaps(void)
944 {
945 
946     LPDIRECTPLAY4 pDP;
947     DPCAPS dpcaps;
948     DWORD dwFlags;
949     HRESULT hr;
950 
951 
952     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
953                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
954     ZeroMemory( &dpcaps, sizeof(DPCAPS) );
955 
956     /* Service provider not ininitialized */
957     hr = IDirectPlayX_GetCaps( pDP, &dpcaps, 0 );
958     checkHR( DPERR_UNINITIALIZED, hr );
959 
960     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
961 
962     /* dpcaps not ininitialized */
963     hr = IDirectPlayX_GetCaps( pDP, &dpcaps, 0 );
964     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
965 
966     dpcaps.dwSize = sizeof(DPCAPS);
967 
968     for (dwFlags=0;
969          dwFlags<=DPGETCAPS_GUARANTEED;
970          dwFlags+=DPGETCAPS_GUARANTEED)
971     {
972 
973         hr = IDirectPlayX_GetCaps( pDP, &dpcaps, dwFlags );
974         todo_wine checkHR( DP_OK, hr );
975 
976 
977         if ( hr == DP_OK )
978         {
979             check( sizeof(DPCAPS), dpcaps.dwSize );
980             check( DPCAPS_ASYNCSUPPORTED |
981                    DPCAPS_GUARANTEEDOPTIMIZED |
982                    DPCAPS_GUARANTEEDSUPPORTED,
983                    dpcaps.dwFlags );
984             check( 0,     dpcaps.dwMaxQueueSize );
985             check( 0,     dpcaps.dwHundredBaud );
986             check( 500,   dpcaps.dwLatency );
987             check( 65536, dpcaps.dwMaxLocalPlayers );
988             check( 20,    dpcaps.dwHeaderLength );
989             check( 5000,  dpcaps.dwTimeout );
990 
991             switch (dwFlags)
992             {
993             case 0:
994                 check( 65479,   dpcaps.dwMaxBufferSize );
995                 check( 65536,   dpcaps.dwMaxPlayers );
996                 break;
997             case DPGETCAPS_GUARANTEED:
998                 check( 1048547, dpcaps.dwMaxBufferSize );
999                 check( 64,      dpcaps.dwMaxPlayers );
1000                 break;
1001             default: break;
1002             }
1003         }
1004     }
1005 
1006     IDirectPlayX_Release( pDP );
1007 }
1008 
1009 /* Open */
1010 
1011 static BOOL CALLBACK EnumSessions_cb2( LPCDPSESSIONDESC2 lpThisSD,
1012                                        LPDWORD lpdwTimeOut,
1013                                        DWORD dwFlags,
1014                                        LPVOID lpContext )
1015 {
1016     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
1017     DPSESSIONDESC2 dpsd;
1018     HRESULT hr;
1019 
1020     if (dwFlags & DPESC_TIMEDOUT)
1021         return FALSE;
1022 
1023 
1024     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1025     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1026     dpsd.guidApplication = appGuid;
1027     dpsd.guidInstance = lpThisSD->guidInstance;
1028 
1029     if ( lpThisSD->dwFlags & DPSESSION_PASSWORDREQUIRED )
1030     {
1031         /* Incorrect password */
1032         U2(dpsd).lpszPasswordA = (LPSTR) "sonic boom";
1033         hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1034         checkHR( DPERR_INVALIDPASSWORD, hr );
1035 
1036         /* Correct password */
1037         U2(dpsd).lpszPasswordA = (LPSTR) "hadouken";
1038         hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1039         checkHR( DP_OK, hr );
1040     }
1041     else
1042     {
1043         hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1044         checkHR( DP_OK, hr );
1045     }
1046 
1047     hr = IDirectPlayX_Close( pDP );
1048     checkHR( DP_OK, hr );
1049 
1050     return TRUE;
1051 }
1052 
1053 static void test_Open(void)
1054 {
1055 
1056     LPDIRECTPLAY4 pDP, pDP_server;
1057     DPSESSIONDESC2 dpsd, dpsd_server;
1058     HRESULT hr;
1059 
1060 
1061     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1062                       &IID_IDirectPlay4A, (LPVOID*) &pDP_server );
1063     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1064                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
1065     ZeroMemory( &dpsd_server, sizeof(DPSESSIONDESC2) );
1066     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1067 
1068     /* Service provider not initialized */
1069     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1070     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1071 
1072     init_TCPIP_provider( pDP_server, "127.0.0.1", 0 );
1073     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
1074 
1075     /* Uninitialized  dpsd */
1076     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1077     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1078 
1079 
1080     dpsd_server.dwSize = sizeof(DPSESSIONDESC2);
1081     dpsd_server.guidApplication = appGuid;
1082     dpsd_server.dwMaxPlayers = 10;
1083 
1084 
1085     /* Regular operation */
1086     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1087     todo_wine checkHR( DP_OK, hr );
1088 
1089     /* Opening twice */
1090     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1091     todo_wine checkHR( DPERR_ALREADYINITIALIZED, hr );
1092 
1093     /* Session flags */
1094     IDirectPlayX_Close( pDP_server );
1095 
1096     dpsd_server.dwFlags = DPSESSION_CLIENTSERVER | DPSESSION_MIGRATEHOST;
1097     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1098     todo_wine checkHR( DPERR_INVALIDFLAGS, hr );
1099 
1100     dpsd_server.dwFlags = DPSESSION_MULTICASTSERVER | DPSESSION_MIGRATEHOST;
1101     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1102     todo_wine checkHR( DPERR_INVALIDFLAGS, hr );
1103 
1104     dpsd_server.dwFlags = DPSESSION_SECURESERVER | DPSESSION_MIGRATEHOST;
1105     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1106     todo_wine checkHR( DPERR_INVALIDFLAGS, hr );
1107 
1108 
1109     /* Joining sessions */
1110     /* - Checking how strict dplay is with sizes */
1111     dpsd.dwSize = 0;
1112     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1113     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1114 
1115     dpsd.dwSize = sizeof(DPSESSIONDESC2)-1;
1116     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1117     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1118 
1119     dpsd.dwSize = sizeof(DPSESSIONDESC2)+1;
1120     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1121     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1122 
1123     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1124     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1125     todo_wine checkHR( DPERR_NOSESSIONS, hr ); /* Only checks for size, not guids */
1126 
1127 
1128     dpsd.guidApplication = appGuid;
1129     dpsd.guidInstance = appGuid;
1130 
1131 
1132     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN );
1133     todo_wine checkHR( DPERR_NOSESSIONS, hr );
1134     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_JOIN | DPOPEN_CREATE );
1135     todo_wine checkHR( DPERR_NOSESSIONS, hr ); /* Second flag is ignored */
1136 
1137     dpsd_server.dwFlags = 0;
1138 
1139 
1140     /* Join to normal session */
1141     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1142     todo_wine checkHR( DP_OK, hr );
1143 
1144     IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb2, pDP, 0 );
1145 
1146 
1147     /* Already initialized session */
1148     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1149     todo_wine checkHR( DPERR_ALREADYINITIALIZED, hr );
1150 
1151 
1152     /* Checking which is the error checking order */
1153     dpsd_server.dwSize = 0;
1154 
1155     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1156     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1157 
1158     dpsd_server.dwSize = sizeof(DPSESSIONDESC2);
1159 
1160 
1161     /* Join to protected session */
1162     IDirectPlayX_Close( pDP_server );
1163     U2(dpsd_server).lpszPasswordA = (LPSTR) "hadouken";
1164     hr = IDirectPlayX_Open( pDP_server, &dpsd_server, DPOPEN_CREATE );
1165     todo_wine checkHR( DP_OK, hr );
1166 
1167     IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb2,
1168                                pDP, DPENUMSESSIONS_PASSWORDREQUIRED );
1169 
1170 
1171     IDirectPlayX_Release( pDP );
1172     IDirectPlayX_Release( pDP_server );
1173 
1174 }
1175 
1176 /* EnumSessions */
1177 
1178 static BOOL CALLBACK EnumSessions_cb( LPCDPSESSIONDESC2 lpThisSD,
1179                                       LPDWORD lpdwTimeOut,
1180                                       DWORD dwFlags,
1181                                       LPVOID lpContext )
1182 {
1183     lpCallbackData callbackData = (lpCallbackData) lpContext;
1184     callbackData->dwCounter1++;
1185 
1186     if ( dwFlags & DPESC_TIMEDOUT )
1187     {
1188         check( TRUE, lpThisSD == NULL );
1189         return FALSE;
1190     }
1191     check( FALSE, lpThisSD == NULL );
1192 
1193 
1194     if ( U2(*lpThisSD).lpszPasswordA != NULL )
1195     {
1196         check( TRUE, (lpThisSD->dwFlags & DPSESSION_PASSWORDREQUIRED) != 0 );
1197     }
1198 
1199     if ( lpThisSD->dwFlags & DPSESSION_NEWPLAYERSDISABLED )
1200     {
1201         check( 0, lpThisSD->dwCurrentPlayers );
1202     }
1203 
1204     check( sizeof(*lpThisSD), lpThisSD->dwSize );
1205     checkLP( NULL, U2(*lpThisSD).lpszPasswordA );
1206 
1207     return TRUE;
1208 }
1209 
1210 static LPDIRECTPLAY4 create_session(DPSESSIONDESC2 *lpdpsd)
1211 {
1212 
1213     LPDIRECTPLAY4 pDP;
1214     DPNAME name;
1215     DPID dpid;
1216     HRESULT hr;
1217 
1218     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1219                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
1220 
1221     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
1222 
1223     hr = IDirectPlayX_Open( pDP, lpdpsd, DPOPEN_CREATE );
1224     todo_wine checkHR( DP_OK, hr );
1225 
1226     if ( ! (lpdpsd->dwFlags & DPSESSION_NEWPLAYERSDISABLED) )
1227     {
1228         ZeroMemory( &name, sizeof(DPNAME) );
1229         name.dwSize = sizeof(DPNAME);
1230         U1(name).lpszShortNameA = (LPSTR) "bofh";
1231 
1232         hr = IDirectPlayX_CreatePlayer( pDP, &dpid, &name, NULL, NULL,
1233                                         0, DPPLAYER_SERVERPLAYER );
1234         todo_wine checkHR( DP_OK, hr );
1235     }
1236 
1237     return pDP;
1238 
1239 }
1240 
1241 static void test_EnumSessions(void)
1242 {
1243 
1244 #define N_SESSIONS 6
1245 
1246     LPDIRECTPLAY4 pDP, pDPserver[N_SESSIONS];
1247     DPSESSIONDESC2 dpsd, dpsd_server[N_SESSIONS];
1248     CallbackData callbackData;
1249     HRESULT hr;
1250     UINT i;
1251 
1252 
1253     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1254                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
1255     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1256     callbackData.dwCounter1 = -1; /* So that after a call to EnumSessions
1257                                      we get the exact number of sessions */
1258     callbackData.dwFlags = 0;
1259 
1260 
1261     /* Service provider not initialized */
1262     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1263                                     &callbackData, 0 );
1264     checkHR( DPERR_UNINITIALIZED, hr );
1265 
1266 
1267     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
1268 
1269 
1270     /* Session with no size */
1271     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1272                                     &callbackData, 0 );
1273     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1274 
1275     if ( hr == DPERR_UNINITIALIZED )
1276     {
1277         todo_wine win_skip( "EnumSessions not implemented\n" );
1278         return;
1279     }
1280 
1281     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1282 
1283 
1284     /* No sessions */
1285     callbackData.dwCounter1 = -1;
1286     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1287                                     &callbackData, 0 );
1288     checkHR( DP_OK, hr );
1289     check( 0, callbackData.dwCounter1 );
1290 
1291 
1292     dpsd.guidApplication = appGuid;
1293 
1294     /* Set up sessions */
1295     for (i=0; i<N_SESSIONS; i++)
1296     {
1297         memcpy( &dpsd_server[i], &dpsd, sizeof(DPSESSIONDESC2) );
1298     }
1299 
1300     U1(dpsd_server[0]).lpszSessionNameA = (LPSTR) "normal";
1301     dpsd_server[0].dwFlags = ( DPSESSION_CLIENTSERVER |
1302                                DPSESSION_DIRECTPLAYPROTOCOL );
1303     dpsd_server[0].dwMaxPlayers = 10;
1304 
1305     U1(dpsd_server[1]).lpszSessionNameA = (LPSTR) "full";
1306     dpsd_server[1].dwFlags = ( DPSESSION_CLIENTSERVER |
1307                                DPSESSION_DIRECTPLAYPROTOCOL );
1308     dpsd_server[1].dwMaxPlayers = 1;
1309 
1310     U1(dpsd_server[2]).lpszSessionNameA = (LPSTR) "no new";
1311     dpsd_server[2].dwFlags = ( DPSESSION_CLIENTSERVER |
1312                                DPSESSION_DIRECTPLAYPROTOCOL |
1313                                DPSESSION_NEWPLAYERSDISABLED );
1314     dpsd_server[2].dwMaxPlayers = 10;
1315 
1316     U1(dpsd_server[3]).lpszSessionNameA = (LPSTR) "no join";
1317     dpsd_server[3].dwFlags = ( DPSESSION_CLIENTSERVER |
1318                                DPSESSION_DIRECTPLAYPROTOCOL |
1319                                DPSESSION_JOINDISABLED );
1320     dpsd_server[3].dwMaxPlayers = 10;
1321 
1322     U1(dpsd_server[4]).lpszSessionNameA = (LPSTR) "private";
1323     dpsd_server[4].dwFlags = ( DPSESSION_CLIENTSERVER |
1324                                DPSESSION_DIRECTPLAYPROTOCOL |
1325                                DPSESSION_PRIVATE );
1326     dpsd_server[4].dwMaxPlayers = 10;
1327     U2(dpsd_server[4]).lpszPasswordA = (LPSTR) "password";
1328 
1329     U1(dpsd_server[5]).lpszSessionNameA = (LPSTR) "protected";
1330     dpsd_server[5].dwFlags = ( DPSESSION_CLIENTSERVER |
1331                                DPSESSION_DIRECTPLAYPROTOCOL |
1332                                DPSESSION_PASSWORDREQUIRED );
1333     dpsd_server[5].dwMaxPlayers = 10;
1334     U2(dpsd_server[5]).lpszPasswordA = (LPSTR) "password";
1335 
1336 
1337     for (i=0; i<N_SESSIONS; i++)
1338     {
1339         pDPserver[i] = create_session( &dpsd_server[i] );
1340     }
1341 
1342 
1343     /* Invalid params */
1344     callbackData.dwCounter1 = -1;
1345     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1346                                     &callbackData, -1 );
1347     checkHR( DPERR_INVALIDPARAMS, hr );
1348 
1349     hr = IDirectPlayX_EnumSessions( pDP, NULL, 0, EnumSessions_cb,
1350                                     &callbackData, 0 );
1351     checkHR( DPERR_INVALIDPARAMS, hr );
1352 
1353     check( -1, callbackData.dwCounter1 );
1354 
1355 
1356     /* Flag tests */
1357     callbackData.dwFlags = DPENUMSESSIONS_ALL; /* Doesn't list private,
1358                                                   protected */
1359     callbackData.dwCounter1 = -1;
1360     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1361                                     &callbackData, callbackData.dwFlags );
1362     check( N_SESSIONS-2, callbackData.dwCounter1 );
1363 
1364     /* Doesn't list private */
1365     callbackData.dwFlags = ( DPENUMSESSIONS_ALL |
1366                              DPENUMSESSIONS_PASSWORDREQUIRED );
1367     callbackData.dwCounter1 = -1;
1368     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1369                                     &callbackData, callbackData.dwFlags );
1370     check( N_SESSIONS-1, callbackData.dwCounter1 );
1371 
1372     /* Doesn't list full, no new, no join, private, protected */
1373     callbackData.dwFlags = DPENUMSESSIONS_AVAILABLE;
1374     callbackData.dwCounter1 = -1;
1375     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1376                                     &callbackData, callbackData.dwFlags );
1377     check( N_SESSIONS-5, callbackData.dwCounter1 );
1378 
1379     /* Like with DPENUMSESSIONS_AVAILABLE */
1380     callbackData.dwFlags = 0;
1381     callbackData.dwCounter1 = -1;
1382     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1383                                     &callbackData, callbackData.dwFlags );
1384     check( N_SESSIONS-5, callbackData.dwCounter1 );
1385 
1386     /* Doesn't list full, no new, no join, private */
1387     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1388     callbackData.dwCounter1 = -1;
1389     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1390                                     &callbackData, callbackData.dwFlags );
1391     check( N_SESSIONS-4, callbackData.dwCounter1 );
1392 
1393 
1394     /* Async enumeration */
1395     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1396     callbackData.dwCounter1 = -1;
1397     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1398                                     &callbackData, callbackData.dwFlags );
1399     check( N_SESSIONS-4, callbackData.dwCounter1 ); /* Read cache of last
1400                                                        sync enumeration */
1401 
1402     callbackData.dwFlags = DPENUMSESSIONS_STOPASYNC;
1403     callbackData.dwCounter1 = -1;
1404     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1405                                     &callbackData, callbackData.dwFlags );
1406     check( 0, callbackData.dwCounter1 ); /* Stop enumeration */
1407 
1408     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1409     callbackData.dwCounter1 = -1;
1410     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1411                                     &callbackData, callbackData.dwFlags );
1412     check( 0, callbackData.dwCounter1 ); /* Start enumeration */
1413 
1414     Sleep(500); /* Give time to fill the cache */
1415 
1416     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1417     callbackData.dwCounter1 = -1;
1418     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1419                                     &callbackData, callbackData.dwFlags );
1420     check( N_SESSIONS-5, callbackData.dwCounter1 ); /* Retrieve results */
1421 
1422     callbackData.dwFlags = DPENUMSESSIONS_STOPASYNC;
1423     callbackData.dwCounter1 = -1;
1424     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1425                                     &callbackData, callbackData.dwFlags );
1426     check( 0, callbackData.dwCounter1 ); /* Stop enumeration */
1427 
1428 
1429     /* Specific tests for passworded sessions */
1430 
1431     for (i=0; i<N_SESSIONS; i++)
1432     {
1433         IDirectPlayX_Release( pDPserver[i] );
1434     }
1435 
1436     /* - Only session password set */
1437     for (i=4;i<=5;i++)
1438     {
1439         U2(dpsd_server[i]).lpszPasswordA = (LPSTR) "password";
1440         dpsd_server[i].dwFlags = 0;
1441         pDPserver[i] = create_session( &dpsd_server[i] );
1442     }
1443 
1444     callbackData.dwFlags = 0;
1445     callbackData.dwCounter1 = -1;
1446     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1447                                     &callbackData, callbackData.dwFlags );
1448     check( 0, callbackData.dwCounter1 );
1449 
1450     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1451     callbackData.dwCounter1 = -1;
1452     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1453                                     &callbackData, callbackData.dwFlags );
1454     check( 2, callbackData.dwCounter1 ); /* Both sessions automatically
1455                                             set DPSESSION_PASSWORDREQUIRED */
1456 
1457     /* - Only session flag set */
1458     for (i=4; i<=5; i++)
1459     {
1460         IDirectPlayX_Release( pDPserver[i] );
1461         U2(dpsd_server[i]).lpszPasswordA = NULL;
1462     }
1463     dpsd_server[4].dwFlags = DPSESSION_PRIVATE;
1464     dpsd_server[5].dwFlags = DPSESSION_PASSWORDREQUIRED;
1465     for (i=4; i<=5; i++)
1466     {
1467         pDPserver[i] = create_session( &dpsd_server[i] );
1468     }
1469 
1470     callbackData.dwFlags = 0;
1471     callbackData.dwCounter1 = -1;
1472     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1473                                     &callbackData, callbackData.dwFlags );
1474     check( 2, callbackData.dwCounter1 ); /* Without password,
1475                                             the flag is ignored */
1476 
1477     /* - Both session flag and password set */
1478     for (i=4; i<=5; i++)
1479     {
1480         IDirectPlayX_Release( pDPserver[i] );
1481         U2(dpsd_server[i]).lpszPasswordA = (LPSTR) "password";
1482     }
1483     dpsd_server[4].dwFlags = DPSESSION_PRIVATE;
1484     dpsd_server[5].dwFlags = DPSESSION_PASSWORDREQUIRED;
1485     for (i=4; i<=5; i++)
1486     {
1487         pDPserver[i] = create_session( &dpsd_server[i] );
1488     }
1489 
1490     /* - Listing without password */
1491     callbackData.dwCounter1 = -1;
1492     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1493                                     &callbackData, callbackData.dwFlags );
1494     check( 0, callbackData.dwCounter1 );
1495 
1496     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1497     callbackData.dwCounter1 = -1;
1498     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1499                                     &callbackData, callbackData.dwFlags );
1500     check( 1, callbackData.dwCounter1 );
1501 
1502     /* - Listing with incorrect password */
1503     U2(dpsd).lpszPasswordA = (LPSTR) "bad_password";
1504     callbackData.dwFlags = 0;
1505     callbackData.dwCounter1 = -1;
1506     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1507                                     &callbackData, callbackData.dwFlags );
1508     check( 0, callbackData.dwCounter1 );
1509 
1510     callbackData.dwFlags = DPENUMSESSIONS_PASSWORDREQUIRED;
1511     callbackData.dwCounter1 = -1;
1512     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1513                                     &callbackData, callbackData.dwFlags );
1514     check( 1, callbackData.dwCounter1 );
1515 
1516     /* - Listing with  correct password */
1517     U2(dpsd).lpszPasswordA = (LPSTR) "password";
1518     callbackData.dwCounter1 = -1;
1519     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1520                                     &callbackData, callbackData.dwFlags );
1521     check( 2, callbackData.dwCounter1 );
1522 
1523 
1524     U2(dpsd).lpszPasswordA = NULL;
1525     callbackData.dwFlags = DPENUMSESSIONS_ASYNC;
1526     callbackData.dwCounter1 = -1;
1527     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1528                                     &callbackData, callbackData.dwFlags );
1529     check( 2, callbackData.dwCounter1 ); /* Read cache of last sync enumeration,
1530                                             even private sessions */
1531 
1532 
1533     /* GUID tests */
1534 
1535     /* - Creating two servers with different application GUIDs */
1536     for (i=4; i<=5; i++)
1537     {
1538         IDirectPlayX_Release( pDPserver[i] );
1539         dpsd_server[i].dwFlags = ( DPSESSION_CLIENTSERVER |
1540                                    DPSESSION_DIRECTPLAYPROTOCOL );
1541         U2(dpsd_server[i]).lpszPasswordA = NULL;
1542         dpsd_server[i].dwMaxPlayers = 10;
1543     }
1544     U1(dpsd_server[4]).lpszSessionNameA = (LPSTR) "normal1";
1545     dpsd_server[4].guidApplication = appGuid;
1546     U1(dpsd_server[5]).lpszSessionNameA = (LPSTR) "normal2";
1547     dpsd_server[5].guidApplication = appGuid2;
1548     for (i=4; i<=5; i++)
1549     {
1550         pDPserver[i] = create_session( &dpsd_server[i] );
1551     }
1552 
1553     callbackData.dwFlags = 0;
1554 
1555     dpsd.guidApplication = appGuid2;
1556     callbackData.dwCounter1 = -1;
1557     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1558                                     &callbackData, callbackData.dwFlags );
1559     check( 1, callbackData.dwCounter1 ); /* Only one of the sessions */
1560 
1561     dpsd.guidApplication = appGuid;
1562     callbackData.dwCounter1 = -1;
1563     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1564                                     &callbackData, callbackData.dwFlags );
1565     check( 1, callbackData.dwCounter1 ); /* The other session */
1566     /* FIXME:
1567        For some reason, if we enum 1st with appGuid and 2nd with appGuid2,
1568        in the second enum we get the 2 sessions. Dplay fault? Elves? */
1569 
1570     dpsd.guidApplication = GUID_NULL;
1571     callbackData.dwCounter1 = -1;
1572     hr = IDirectPlayX_EnumSessions( pDP, &dpsd, 0, EnumSessions_cb,
1573                                     &callbackData, callbackData.dwFlags );
1574     check( 2, callbackData.dwCounter1 ); /* Both sessions */
1575 
1576     for (i=4; i<=5; i++)
1577     {
1578         IDirectPlayX_Release( pDPserver[i] );
1579     }
1580     IDirectPlayX_Release( pDP );
1581 
1582 }
1583 
1584 /* SetSessionDesc
1585    GetSessionDesc */
1586 
1587 static void test_SessionDesc(void)
1588 {
1589 
1590     LPDIRECTPLAY4 pDP[2];
1591     DPSESSIONDESC2 dpsd;
1592     LPDPSESSIONDESC2 lpData[2];
1593     LPVOID lpDataMsg;
1594     DPID dpid[2];
1595     DWORD dwDataSize;
1596     HRESULT hr;
1597     UINT i;
1598     CallbackData callbackData;
1599 
1600 
1601     for (i=0; i<2; i++)
1602     {
1603         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1604                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
1605     }
1606     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1607 
1608     /* Service provider not initialized */
1609     hr = IDirectPlayX_SetSessionDesc( pDP[0], NULL, 0 );
1610     checkHR( DPERR_UNINITIALIZED, hr );
1611 
1612     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, NULL );
1613     checkHR( DPERR_UNINITIALIZED, hr );
1614 
1615 
1616     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
1617     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
1618 
1619 
1620     /* No sessions open */
1621     hr = IDirectPlayX_SetSessionDesc( pDP[0], NULL, 0 );
1622     todo_wine checkHR( DPERR_NOSESSIONS, hr );
1623 
1624     if ( hr == DPERR_UNINITIALIZED )
1625     {
1626         todo_wine win_skip("Get/SetSessionDesc not implemented\n");
1627         return;
1628     }
1629 
1630     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, NULL );
1631     checkHR( DPERR_NOSESSIONS, hr );
1632 
1633 
1634     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1635     dpsd.guidApplication = appGuid;
1636     dpsd.dwMaxPlayers = 10;
1637 
1638 
1639     /* Host */
1640     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1641     /* Peer */
1642     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
1643                                pDP[1], 0 );
1644 
1645     for (i=0; i<2; i++)
1646     {
1647         /* Players, only to receive messages */
1648         IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL, 0, 0 );
1649 
1650         lpData[i] = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
1651     }
1652     lpDataMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 );
1653 
1654 
1655     /* Incorrect parameters */
1656     hr = IDirectPlayX_SetSessionDesc( pDP[0], NULL, 0 );
1657     checkHR( DPERR_INVALIDPARAMS, hr );
1658     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, NULL );
1659     checkHR( DPERR_INVALIDPARAM, hr );
1660     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], NULL );
1661     checkHR( DPERR_INVALIDPARAM, hr );
1662     dwDataSize=-1;
1663     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1664     checkHR( DPERR_INVALIDPARAMS, hr );
1665     check( -1, dwDataSize );
1666 
1667     /* Get: Insufficient buffer size */
1668     dwDataSize=0;
1669     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1670     checkHR( DPERR_BUFFERTOOSMALL, hr );
1671     check( dpsd.dwSize, dwDataSize );
1672     dwDataSize=4;
1673     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1674     checkHR( DPERR_BUFFERTOOSMALL, hr );
1675     check( dpsd.dwSize, dwDataSize );
1676     dwDataSize=1024;
1677     hr = IDirectPlayX_GetSessionDesc( pDP[0], NULL, &dwDataSize );
1678     checkHR( DPERR_BUFFERTOOSMALL, hr );
1679     check( dpsd.dwSize, dwDataSize );
1680 
1681     /* Get: Regular operation
1682      *  i=0: Local session
1683      *  i=1: Remote session */
1684     for (i=0; i<2; i++)
1685     {
1686         hr = IDirectPlayX_GetSessionDesc( pDP[i], lpData[i], &dwDataSize );
1687         checkHR( DP_OK, hr );
1688         check( sizeof(DPSESSIONDESC2), dwDataSize );
1689         check( sizeof(DPSESSIONDESC2), lpData[i]->dwSize );
1690         checkGuid( &appGuid, &lpData[i]->guidApplication );
1691         check( dpsd.dwMaxPlayers, lpData[i]->dwMaxPlayers );
1692     }
1693 
1694     checkGuid( &lpData[0]->guidInstance, &lpData[1]->guidInstance );
1695 
1696     /* Set: Regular operation */
1697     U1(dpsd).lpszSessionNameA = (LPSTR) "Wahaa";
1698     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1699     checkHR( DP_OK, hr );
1700 
1701     dwDataSize = 1024;
1702     hr = IDirectPlayX_GetSessionDesc( pDP[1], lpData[1], &dwDataSize );
1703     checkHR( DP_OK, hr );
1704     checkStr( U1(dpsd).lpszSessionNameA, U1(*lpData[1]).lpszSessionNameA );
1705 
1706 
1707     /* Set: Failing to modify a remote session */
1708     hr = IDirectPlayX_SetSessionDesc( pDP[1], &dpsd, 0 );
1709     checkHR( DPERR_ACCESSDENIED, hr );
1710 
1711     /* Trying to change inmutable properties */
1712     /*  Flags */
1713     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1714     checkHR( DP_OK, hr );
1715     dpsd.dwFlags = DPSESSION_SECURESERVER;
1716     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1717     checkHR( DPERR_INVALIDPARAMS, hr );
1718     dpsd.dwFlags = 0;
1719     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1720     checkHR( DP_OK, hr );
1721     /*  Size */
1722     dpsd.dwSize = 2048;
1723     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1724     checkHR( DPERR_INVALIDPARAMS, hr );
1725     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1726     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1727     checkHR( DP_OK, hr );
1728 
1729     /* Changing the GUIDs and size is ignored */
1730     dpsd.guidApplication = appGuid2;
1731     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1732     checkHR( DP_OK, hr );
1733     dpsd.guidInstance = appGuid2;
1734     hr = IDirectPlayX_SetSessionDesc( pDP[0], &dpsd, 0 );
1735     checkHR( DP_OK, hr );
1736 
1737     hr = IDirectPlayX_GetSessionDesc( pDP[0], lpData[0], &dwDataSize );
1738     checkHR( DP_OK, hr );
1739     checkGuid( &appGuid, &lpData[0]->guidApplication );
1740     checkGuid( &lpData[1]->guidInstance, &lpData[0]->guidInstance );
1741     check( sizeof(DPSESSIONDESC2), lpData[0]->dwSize );
1742 
1743 
1744     /* Checking system messages */
1745     check_messages( pDP[0], dpid, 2, &callbackData );
1746     checkStr( "S0,S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
1747     checkStr( "48,90,90,90,90,90,90,", callbackData.szTrace2 );
1748     check_messages( pDP[1], dpid, 2, &callbackData );
1749     checkStr( "S1,S1,S1,S1,S1,S1,", callbackData.szTrace1 );
1750     checkStr( "90,90,90,90,90,90,", callbackData.szTrace2 );
1751 
1752     HeapFree( GetProcessHeap(), 0, lpDataMsg );
1753     for (i=0; i<2; i++)
1754     {
1755         HeapFree( GetProcessHeap(), 0, lpData[i] );
1756         IDirectPlayX_Release( pDP[i] );
1757     }
1758 
1759 }
1760 
1761 /* CreatePlayer */
1762 
1763 static void test_CreatePlayer(void)
1764 {
1765 
1766     LPDIRECTPLAY4 pDP[2];
1767     DPSESSIONDESC2 dpsd;
1768     DPNAME name;
1769     DPID dpid;
1770     HRESULT hr;
1771 
1772 
1773     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1774                       &IID_IDirectPlay4A, (LPVOID*) &pDP[0] );
1775     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1776                       &IID_IDirectPlay4A, (LPVOID*) &pDP[1] );
1777     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1778     ZeroMemory( &name, sizeof(DPNAME) );
1779 
1780 
1781     /* Connection not initialized */
1782     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL, 0, 0 );
1783     checkHR( DPERR_UNINITIALIZED, hr );
1784 
1785 
1786     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
1787     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
1788 
1789 
1790     /* Session not open */
1791     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL, 0, 0 );
1792     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1793 
1794     if ( hr == DPERR_UNINITIALIZED )
1795     {
1796         todo_wine win_skip( "CreatePlayer not implemented\n" );
1797         return;
1798     }
1799 
1800     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1801     dpsd.guidApplication = appGuid;
1802     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1803 
1804 
1805     /* Player name */
1806     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL, 0, 0 );
1807     checkHR( DP_OK, hr );
1808 
1809 
1810     name.dwSize = -1;
1811 
1812 
1813     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, &name, NULL, NULL, 0, 0 );
1814     checkHR( DP_OK, hr );
1815 
1816 
1817     name.dwSize = sizeof(DPNAME);
1818     U1(name).lpszShortNameA = (LPSTR) "test";
1819     U2(name).lpszLongNameA = NULL;
1820 
1821 
1822     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, &name, NULL, NULL,
1823                                     0, 0 );
1824     checkHR( DP_OK, hr );
1825 
1826 
1827     /* Null dpid */
1828     hr = IDirectPlayX_CreatePlayer( pDP[0], NULL, NULL, NULL, NULL,
1829                                     0, 0 );
1830     checkHR( DPERR_INVALIDPARAMS, hr );
1831 
1832 
1833     /* There can only be one server player */
1834     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1835                                     0, DPPLAYER_SERVERPLAYER );
1836     checkHR( DP_OK, hr );
1837     check( DPID_SERVERPLAYER, dpid );
1838 
1839     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1840                                     0, DPPLAYER_SERVERPLAYER );
1841     checkHR( DPERR_CANTCREATEPLAYER, hr );
1842 
1843     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1844 
1845     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1846                                     0, DPPLAYER_SERVERPLAYER );
1847     checkHR( DP_OK, hr );
1848     check( DPID_SERVERPLAYER, dpid );
1849     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1850 
1851 
1852     /* Flags */
1853     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1854                                     0, 0 );
1855     checkHR( DP_OK, hr );
1856 
1857     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1858                                     0, DPPLAYER_SERVERPLAYER );
1859     checkHR( DP_OK, hr );
1860     check( DPID_SERVERPLAYER, dpid );
1861     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1862 
1863     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1864                                     0, DPPLAYER_SPECTATOR );
1865     checkHR( DP_OK, hr );
1866 
1867     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1868                                     0, ( DPPLAYER_SERVERPLAYER |
1869                                          DPPLAYER_SPECTATOR ) );
1870     checkHR( DP_OK, hr );
1871     check( DPID_SERVERPLAYER, dpid );
1872     IDirectPlayX_DestroyPlayer( pDP[0], dpid );
1873 
1874 
1875     /* Session with DPSESSION_NEWPLAYERSDISABLED */
1876     IDirectPlayX_Close( pDP[0] );
1877     dpsd.dwFlags = DPSESSION_NEWPLAYERSDISABLED;
1878     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1879     checkHR( DP_OK, hr );
1880 
1881 
1882     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1883                                     0, 0 );
1884     checkHR( DPERR_CANTCREATEPLAYER, hr );
1885 
1886     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1887                                     0, DPPLAYER_SERVERPLAYER );
1888     checkHR( DPERR_CANTCREATEPLAYER, hr );
1889 
1890     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1891                                     0, DPPLAYER_SPECTATOR );
1892     checkHR( DPERR_CANTCREATEPLAYER, hr );
1893 
1894 
1895     /* Creating players in a Client/Server session */
1896     IDirectPlayX_Close( pDP[0] );
1897     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
1898     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1899     checkHR( DP_OK, hr );
1900     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
1901                                     pDP[1], 0 );
1902     checkHR( DP_OK, hr );
1903 
1904 
1905     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1906                                     0, 0 );
1907     checkHR( DPERR_ACCESSDENIED, hr );
1908 
1909     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid, NULL, NULL, NULL,
1910                                     0, DPPLAYER_SERVERPLAYER );
1911     checkHR( DP_OK, hr );
1912     check( DPID_SERVERPLAYER, dpid );
1913 
1914     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid, NULL, NULL, NULL,
1915                                     0, DPPLAYER_SERVERPLAYER );
1916     checkHR( DPERR_INVALIDFLAGS, hr );
1917 
1918     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid, NULL, NULL, NULL,
1919                                     0, 0 );
1920     checkHR( DP_OK, hr );
1921 
1922 
1923     IDirectPlayX_Release( pDP[0] );
1924     IDirectPlayX_Release( pDP[1] );
1925 
1926 }
1927 
1928 /* GetPlayerCaps */
1929 
1930 static void test_GetPlayerCaps(void)
1931 {
1932 
1933     LPDIRECTPLAY4 pDP[2];
1934     DPSESSIONDESC2 dpsd;
1935     DPID dpid[2];
1936     HRESULT hr;
1937     UINT i;
1938 
1939     DPCAPS playerCaps;
1940     DWORD dwFlags;
1941 
1942 
1943     for (i=0; i<2; i++)
1944     {
1945         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
1946                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
1947     }
1948     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
1949     dpsd.dwSize = sizeof(DPSESSIONDESC2);
1950     dpsd.guidApplication = appGuid;
1951     dpsd.dwMaxPlayers = 10;
1952 
1953     ZeroMemory( &playerCaps, sizeof(DPCAPS) );
1954 
1955 
1956     /* Uninitialized service provider */
1957     playerCaps.dwSize = 0;
1958     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1959     checkHR( DPERR_UNINITIALIZED, hr );
1960 
1961     playerCaps.dwSize = sizeof(DPCAPS);
1962     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1963     checkHR( DPERR_UNINITIALIZED, hr );
1964 
1965 
1966     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
1967     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
1968 
1969 
1970     /* No session */
1971     playerCaps.dwSize = 0;
1972 
1973     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1974     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
1975 
1976     if ( hr == DPERR_UNINITIALIZED )
1977     {
1978         todo_wine win_skip( "GetPlayerCaps not implemented\n" );
1979         return;
1980     }
1981 
1982     playerCaps.dwSize = sizeof(DPCAPS);
1983 
1984     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
1985     checkHR( DPERR_INVALIDPLAYER, hr );
1986 
1987     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 2, &playerCaps, 0 );
1988     checkHR( DPERR_INVALIDPLAYER, hr );
1989 
1990 
1991     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
1992     checkHR( DP_OK, hr );
1993     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
1994                                     pDP[1], 0 );
1995     checkHR( DP_OK, hr );
1996 
1997     for (i=0; i<2; i++)
1998     {
1999         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
2000                                         NULL, NULL, NULL, 0, 0 );
2001         checkHR( DP_OK, hr );
2002     }
2003 
2004 
2005     /* Uninitialized playerCaps */
2006     playerCaps.dwSize = 0;
2007 
2008     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
2009     checkHR( DPERR_INVALIDPARAMS, hr );
2010 
2011     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 2, &playerCaps, 0 );
2012     checkHR( DPERR_INVALIDPARAMS, hr );
2013 
2014     hr = IDirectPlayX_GetPlayerCaps( pDP[0], dpid[0], &playerCaps, 0 );
2015     checkHR( DPERR_INVALIDPARAMS, hr );
2016 
2017 
2018     /* Invalid player */
2019     playerCaps.dwSize = sizeof(DPCAPS);
2020 
2021     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 0, &playerCaps, 0 );
2022     checkHR( DPERR_INVALIDPLAYER, hr );
2023 
2024     hr = IDirectPlayX_GetPlayerCaps( pDP[0], 2, &playerCaps, 0 );
2025     checkHR( DPERR_INVALIDPLAYER, hr );
2026 
2027     hr = IDirectPlayX_GetPlayerCaps( pDP[0], dpid[0], &playerCaps, 0 );
2028     checkHR( DP_OK, hr );
2029 
2030 
2031     /* Regular parameters */
2032     for (i=0; i<2; i++)
2033     {
2034         for (dwFlags=0;
2035              dwFlags<=DPGETCAPS_GUARANTEED;
2036              dwFlags+=DPGETCAPS_GUARANTEED)
2037         {
2038 
2039             hr = IDirectPlayX_GetPlayerCaps( pDP[0], dpid[i],
2040                                              &playerCaps, dwFlags );
2041             checkHR( DP_OK, hr );
2042 
2043 
2044             check( sizeof(DPCAPS), playerCaps.dwSize );
2045             check( 40,    playerCaps.dwSize );
2046             check( 0,     playerCaps.dwMaxQueueSize );
2047             check( 0,     playerCaps.dwHundredBaud );
2048             check( 0,     playerCaps.dwLatency );
2049             check( 65536, playerCaps.dwMaxLocalPlayers );
2050             check( 20,    playerCaps.dwHeaderLength );
2051 
2052             if ( i == 0 )
2053             {
2054                 checkFlags( DPCAPS_ISHOST |
2055                             DPCAPS_GUARANTEEDOPTIMIZED |
2056                             DPCAPS_GUARANTEEDSUPPORTED |
2057                             DPCAPS_ASYNCSUPPORTED |
2058                             DPPLAYERCAPS_LOCAL,
2059                             playerCaps.dwFlags, FLAGS_DPCAPS );
2060             }
2061             else
2062                 checkFlags( DPCAPS_ISHOST |
2063                             DPCAPS_GUARANTEEDOPTIMIZED |
2064                             DPCAPS_GUARANTEEDSUPPORTED |
2065                             DPCAPS_ASYNCSUPPORTED,
2066                             playerCaps.dwFlags, FLAGS_DPCAPS );
2067 
2068             if ( dwFlags == DPGETCAPS_GUARANTEED )
2069             {
2070                 check( 1048547, playerCaps.dwMaxBufferSize );
2071                 check( 64,      playerCaps.dwMaxPlayers );
2072             }
2073             else
2074             {
2075                 check( 65479, playerCaps.dwMaxBufferSize );
2076                 check( 65536, playerCaps.dwMaxPlayers );
2077             }
2078 
2079         }
2080     }
2081 
2082 
2083     IDirectPlayX_Release( pDP[0] );
2084     IDirectPlayX_Release( pDP[1] );
2085 
2086 }
2087 
2088 /* SetPlayerData
2089    GetPlayerData */
2090 
2091 static void test_PlayerData(void)
2092 {
2093     LPDIRECTPLAY4 pDP;
2094     DPSESSIONDESC2 dpsd;
2095     DPID dpid;
2096     HRESULT hr;
2097 
2098     /* lpDataFake has to be bigger than the rest, limits lpDataGet size */
2099     LPCSTR lpDataFake     = "big_fake_data_chunk";
2100     DWORD dwDataSizeFake  = strlen(lpDataFake)+1;
2101 
2102     LPCSTR lpData         = "remote_data";
2103     DWORD dwDataSize      = strlen(lpData)+1;
2104 
2105     LPCSTR lpDataLocal    = "local_data";
2106     DWORD dwDataSizeLocal = strlen(lpDataLocal)+1;
2107 
2108     LPSTR lpDataGet       = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
2109                                        dwDataSizeFake );
2110     DWORD dwDataSizeGet   = dwDataSizeFake;
2111 
2112 
2113     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2114                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
2115 
2116     /* No service provider */
2117     hr = IDirectPlayX_SetPlayerData( pDP, 0, (LPVOID) lpData,
2118                                      dwDataSize, 0 );
2119     checkHR( DPERR_UNINITIALIZED, hr );
2120 
2121     hr = IDirectPlayX_GetPlayerData( pDP, 0, lpDataGet, &dwDataSizeGet, 0 );
2122     checkHR( DPERR_UNINITIALIZED, hr );
2123 
2124 
2125     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
2126 
2127     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2128     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2129     dpsd.guidApplication = appGuid;
2130     IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
2131 
2132 
2133     /* Invalid player */
2134     hr = IDirectPlayX_SetPlayerData( pDP, 0, (LPVOID) lpData,
2135                                      dwDataSize, 0 );
2136     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
2137 
2138     hr = IDirectPlayX_GetPlayerData( pDP, 0, lpDataGet, &dwDataSizeGet, 0 );
2139     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
2140 
2141     if ( hr == DPERR_UNINITIALIZED )
2142     {
2143         todo_wine win_skip( "Get/SetPlayerData not implemented\n" );
2144         return;
2145     }
2146 
2147     /* Create the player */
2148     /* By default, the data is remote */
2149     hr = IDirectPlayX_CreatePlayer( pDP, &dpid, NULL, NULL, (LPVOID) lpData,
2150                                     dwDataSize, 0 );
2151     checkHR( DP_OK, hr );
2152 
2153     /* Invalid parameters */
2154     hr = IDirectPlayX_SetPlayerData( pDP, dpid, NULL, dwDataSize, 0 );
2155     checkHR( DPERR_INVALIDPARAMS, hr );
2156     hr = IDirectPlayX_SetPlayerData( pDP, dpid, lpDataGet, -1, 0 );
2157     checkHR( DPERR_INVALIDPARAMS, hr );
2158 
2159     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, NULL, 0 );
2160     checkHR( DPERR_INVALIDPARAMS, hr );
2161 
2162 
2163     /*
2164      * Remote data (default)
2165      */
2166 
2167 
2168     /* Buffer redimension */
2169     dwDataSizeGet = dwDataSizeFake;
2170     strcpy(lpDataGet, lpDataFake);
2171     hr = IDirectPlayX_GetPlayerData( pDP, dpid, NULL,
2172                                      &dwDataSizeGet, 0 );
2173     check( DPERR_BUFFERTOOSMALL, hr );
2174     check( dwDataSize, dwDataSizeGet );
2175     checkStr( lpDataFake, lpDataGet );
2176 
2177     dwDataSizeGet = 2;
2178     strcpy(lpDataGet, lpDataFake);
2179     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2180     check( DPERR_BUFFERTOOSMALL, hr );
2181     check( dwDataSize, dwDataSizeGet );
2182 
2183     strcpy(lpDataGet, lpDataFake);
2184     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2185     checkHR( DP_OK, hr );
2186     check( dwDataSize, dwDataSizeGet );
2187     checkStr( lpData, lpDataGet );
2188 
2189     /* Normal operation */
2190     dwDataSizeGet = dwDataSizeFake;
2191     strcpy(lpDataGet, lpDataFake);
2192     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2193     checkHR( DP_OK, hr );
2194     check( dwDataSize, dwDataSizeGet );
2195     checkStr( lpData, lpDataGet );
2196 
2197     /* Flag tests */
2198     dwDataSizeGet = dwDataSizeFake;
2199     strcpy(lpDataGet, lpDataFake);
2200     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2201     checkHR( DP_OK, hr );
2202     check( dwDataSize, dwDataSizeGet ); /* Remote: works as expected */
2203     checkStr( lpData, lpDataGet );
2204 
2205     dwDataSizeGet = dwDataSizeFake;
2206     strcpy(lpDataGet, lpDataFake);
2207     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2208                                      DPGET_REMOTE );
2209     checkHR( DP_OK, hr );
2210     check( dwDataSize, dwDataSizeGet ); /* Same behaviour as in previous test */
2211     checkStr( lpData, lpDataGet );
2212 
2213     dwDataSizeGet = dwDataSizeFake;
2214     strcpy(lpDataGet, lpDataFake);
2215     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2216                                      DPGET_LOCAL );
2217     checkHR( DP_OK, hr );
2218     check( 0, dwDataSizeGet ); /* Sets size to 0 (as local data doesn't exist) */
2219     checkStr( lpDataFake, lpDataGet );
2220 
2221     dwDataSizeGet = dwDataSizeFake;
2222     strcpy(lpDataGet, lpDataFake);
2223     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2224                                      DPGET_LOCAL | DPGET_REMOTE );
2225     checkHR( DP_OK, hr );
2226     check( 0, dwDataSizeGet ); /* Same behaviour as in previous test */
2227     checkStr( lpDataFake, lpDataGet );
2228 
2229     /* Getting local data (which doesn't exist), buffer size is ignored */
2230     dwDataSizeGet = 0;
2231     strcpy(lpDataGet, lpDataFake);
2232     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2233                                      DPGET_LOCAL );
2234     checkHR( DP_OK, hr );
2235     check( 0, dwDataSizeGet ); /* Sets size to 0 */
2236     checkStr( lpDataFake, lpDataGet );
2237 
2238     dwDataSizeGet = dwDataSizeFake;
2239     strcpy(lpDataGet, lpDataFake);
2240     hr = IDirectPlayX_GetPlayerData( pDP, dpid, NULL, &dwDataSizeGet,
2241                                      DPGET_LOCAL );
2242     checkHR( DP_OK, hr );
2243     check( 0, dwDataSizeGet ); /* Sets size to 0 */
2244     checkStr( lpDataFake, lpDataGet );
2245 
2246 
2247     /*
2248      * Local data
2249      */
2250 
2251 
2252     /* Invalid flags */
2253     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2254                                      dwDataSizeLocal,
2255                                      DPSET_LOCAL | DPSET_GUARANTEED );
2256     checkHR( DPERR_INVALIDPARAMS, hr );
2257 
2258     /* Correct parameters */
2259     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2260                                      dwDataSizeLocal, DPSET_LOCAL );
2261     checkHR( DP_OK, hr );
2262 
2263     /* Flag tests (again) */
2264     dwDataSizeGet = dwDataSizeFake;
2265     strcpy(lpDataGet, lpDataFake);
2266     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2267     checkHR( DP_OK, hr );
2268     check( dwDataSize, dwDataSizeGet ); /* Remote: works as expected */
2269     checkStr( lpData, lpDataGet );
2270 
2271     dwDataSizeGet = dwDataSizeFake;
2272     strcpy(lpDataGet, lpDataFake);
2273     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2274                                      DPGET_REMOTE );
2275     checkHR( DP_OK, hr );
2276     check( dwDataSize, dwDataSizeGet ); /* Like in previous test */
2277     checkStr( lpData, lpDataGet );
2278 
2279     dwDataSizeGet = dwDataSizeFake;
2280     strcpy(lpDataGet, lpDataFake);
2281     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2282                                      DPGET_LOCAL );
2283     checkHR( DP_OK, hr );
2284     check( dwDataSizeLocal, dwDataSizeGet ); /* Local: works as expected */
2285     checkStr( lpDataLocal, lpDataGet );
2286 
2287     dwDataSizeGet = dwDataSizeFake;
2288     strcpy(lpDataGet, lpDataFake);
2289     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2290                                      DPGET_LOCAL | DPGET_REMOTE );
2291     checkHR( DP_OK, hr );
2292     check( dwDataSizeLocal, dwDataSizeGet ); /* Like in previous test */
2293     checkStr( lpDataLocal, lpDataGet );
2294 
2295     /* Small buffer works as expected again */
2296     dwDataSizeGet = 0;
2297     strcpy(lpDataGet, lpDataFake);
2298     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet,
2299                                      DPGET_LOCAL );
2300     checkHR( DPERR_BUFFERTOOSMALL, hr );
2301     check( dwDataSizeLocal, dwDataSizeGet );
2302     checkStr( lpDataFake, lpDataGet );
2303 
2304     dwDataSizeGet = dwDataSizeFake;
2305     strcpy(lpDataGet, lpDataFake);
2306     hr = IDirectPlayX_GetPlayerData( pDP, dpid, NULL,
2307                                      &dwDataSizeGet, DPGET_LOCAL );
2308     check( DPERR_BUFFERTOOSMALL, hr );
2309     check( dwDataSizeLocal, dwDataSizeGet );
2310     checkStr( lpDataFake, lpDataGet );
2311 
2312 
2313     /*
2314      * Changing remote data
2315      */
2316 
2317 
2318     /* Remote data := local data */
2319     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2320                                      dwDataSizeLocal,
2321                                      DPSET_GUARANTEED | DPSET_REMOTE );
2322     checkHR( DP_OK, hr );
2323     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataLocal,
2324                                      dwDataSizeLocal, 0 );
2325     checkHR( DP_OK, hr );
2326 
2327     dwDataSizeGet = dwDataSizeFake;
2328     strcpy(lpDataGet, lpDataFake);
2329     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2330     checkHR( DP_OK, hr );
2331     check( dwDataSizeLocal, dwDataSizeGet );
2332     checkStr( lpDataLocal, lpDataGet );
2333 
2334     /* Remote data := fake data */
2335     hr = IDirectPlayX_SetPlayerData( pDP, dpid, (LPVOID) lpDataFake,
2336                                      dwDataSizeFake, DPSET_REMOTE );
2337     checkHR( DP_OK, hr );
2338 
2339     dwDataSizeGet = dwDataSizeFake + 1;
2340     strcpy(lpDataGet, lpData);
2341     hr = IDirectPlayX_GetPlayerData( pDP, dpid, lpDataGet, &dwDataSizeGet, 0 );
2342     checkHR( DP_OK, hr );
2343     check( dwDataSizeFake, dwDataSizeGet );
2344     checkStr( lpDataFake, lpDataGet );
2345 
2346 
2347     HeapFree( GetProcessHeap(), 0, lpDataGet );
2348     IDirectPlayX_Release( pDP );
2349 }
2350 
2351 /* GetPlayerName
2352    SetPlayerName */
2353 
2354 static void test_PlayerName(void)
2355 {
2356 
2357     LPDIRECTPLAY4 pDP[2];
2358     DPSESSIONDESC2 dpsd;
2359     DPID dpid[2];
2360     HRESULT hr;
2361     UINT i;
2362 
2363     DPNAME playerName;
2364     DWORD dwDataSize = 1024;
2365     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2366     CallbackData callbackData;
2367 
2368 
2369     for (i=0; i<2; i++)
2370     {
2371         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2372                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2373     }
2374     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2375     ZeroMemory( &playerName, sizeof(DPNAME) );
2376 
2377 
2378     /* Service provider not initialized */
2379     hr = IDirectPlayX_SetPlayerName( pDP[0], 0, &playerName, 0 );
2380     checkHR( DPERR_UNINITIALIZED, hr );
2381 
2382     dwDataSize = 1024;
2383     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2384     checkHR( DPERR_UNINITIALIZED, hr );
2385     check( 1024, dwDataSize );
2386 
2387 
2388     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2389     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2390 
2391 
2392     /* Session not initialized */
2393     hr = IDirectPlayX_SetPlayerName( pDP[0], 0, &playerName, 0 );
2394     todo_wine checkHR( DPERR_INVALIDPLAYER, hr );
2395 
2396     if ( hr == DPERR_UNINITIALIZED )
2397     {
2398         todo_wine win_skip( "Get/SetPlayerName not implemented\n" );
2399         return;
2400     }
2401 
2402     dwDataSize = 1024;
2403     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2404     checkHR( DPERR_INVALIDPLAYER, hr );
2405     check( 1024, dwDataSize );
2406 
2407 
2408     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2409     dpsd.guidApplication = appGuid;
2410     dpsd.dwMaxPlayers = 10;
2411     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2412     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2413                                pDP[1], 0 );
2414 
2415     IDirectPlayX_CreatePlayer( pDP[0], &dpid[0], NULL, NULL, NULL, 0, 0 );
2416     IDirectPlayX_CreatePlayer( pDP[1], &dpid[1], NULL, NULL, NULL, 0, 0 );
2417 
2418 
2419     /* Name not initialized */
2420     playerName.dwSize = -1;
2421     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName, 0 );
2422     checkHR( DP_OK, hr );
2423 
2424     dwDataSize = 1024;
2425     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2426     checkHR( DPERR_INVALIDPLAYER, hr );
2427     check( 1024, dwDataSize );
2428 
2429 
2430     playerName.dwSize = sizeof(DPNAME);
2431     U1(playerName).lpszShortNameA = (LPSTR) "player_name";
2432     U2(playerName).lpszLongNameA = (LPSTR) "player_long_name";
2433 
2434 
2435     /* Invalid parameters */
2436     hr = IDirectPlayX_SetPlayerName( pDP[0], -1, &playerName, 0 );
2437     checkHR( DPERR_INVALIDPLAYER, hr );
2438     hr = IDirectPlayX_SetPlayerName( pDP[0], 0, &playerName, 0 );
2439     checkHR( DPERR_INVALIDPLAYER, hr );
2440     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName, -1 );
2441     checkHR( DPERR_INVALIDPARAMS, hr );
2442 
2443     dwDataSize = 1024;
2444     hr = IDirectPlayX_GetPlayerName( pDP[0], 0, lpData, &dwDataSize );
2445     checkHR( DPERR_INVALIDPLAYER, hr );
2446     check( 1024, dwDataSize );
2447 
2448     dwDataSize = -1;
2449     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2450     checkHR( DPERR_INVALIDPARAMS, hr );
2451     check( -1, dwDataSize );
2452 
2453     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, NULL );
2454     checkHR( DPERR_INVALIDPARAMS, hr );
2455 
2456     /* Trying to modify remote player */
2457     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[1], &playerName, 0 );
2458     checkHR( DPERR_ACCESSDENIED, hr );
2459 
2460 
2461     /* Regular operation */
2462     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName, 0 );
2463 
2464     dwDataSize = 1024;
2465     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2466     checkHR( DP_OK, hr );
2467     check( 45, dwDataSize );
2468     checkStr( U1(playerName).lpszShortNameA, U1(*(LPDPNAME)lpData).lpszShortNameA );
2469     checkStr( U2(playerName).lpszLongNameA,  U2(*(LPDPNAME)lpData).lpszLongNameA );
2470     check( 0,                            ((LPDPNAME)lpData)->dwFlags );
2471 
2472     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], NULL, 0 );
2473 
2474     dwDataSize = 1024;
2475     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2476     checkHR( DP_OK, hr );
2477     check( 16, dwDataSize );
2478     checkLP( NULL, U1(*(LPDPNAME)lpData).lpszShortNameA );
2479     checkLP( NULL, U2(*(LPDPNAME)lpData).lpszLongNameA );
2480     check( 0,      ((LPDPNAME)lpData)->dwFlags );
2481 
2482 
2483     /* Small buffer in get operation */
2484     dwDataSize = 1024;
2485     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], NULL, &dwDataSize );
2486     checkHR( DPERR_BUFFERTOOSMALL, hr );
2487     check( 16, dwDataSize );
2488 
2489     dwDataSize = 0;
2490     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2491     checkHR( DPERR_BUFFERTOOSMALL, hr );
2492     check( 16, dwDataSize );
2493 
2494     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0], lpData, &dwDataSize );
2495     checkHR( DP_OK, hr );
2496     check( 16, dwDataSize );
2497     checkLP( NULL, U1(*(LPDPNAME)lpData).lpszShortNameA );
2498     checkLP( NULL, U2(*(LPDPNAME)lpData).lpszLongNameA );
2499     check( 0, ((LPDPNAME)lpData)->dwFlags );
2500 
2501 
2502     /* Flags */
2503     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2504                                      DPSET_GUARANTEED );
2505     checkHR( DP_OK, hr );
2506 
2507     /* - Local (no propagation) */
2508     U1(playerName).lpszShortNameA = (LPSTR) "no_propagation";
2509     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2510                                      DPSET_LOCAL );
2511     checkHR( DP_OK, hr );
2512 
2513     dwDataSize = 1024;
2514     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0],
2515                                      lpData, &dwDataSize ); /* Local fetch */
2516     checkHR( DP_OK, hr );
2517     check( 48, dwDataSize );
2518     checkStr( "no_propagation", U1(*(LPDPNAME)lpData).lpszShortNameA );
2519 
2520     dwDataSize = 1024;
2521     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2522                                      lpData, &dwDataSize ); /* Remote fetch */
2523     checkHR( DP_OK, hr );
2524     check( 45, dwDataSize );
2525     checkStr( "player_name", U1(*(LPDPNAME)lpData).lpszShortNameA );
2526 
2527     /* -- 2 */
2528 
2529     U1(playerName).lpszShortNameA = (LPSTR) "no_propagation_2";
2530     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2531                                      DPSET_LOCAL | DPSET_REMOTE );
2532     checkHR( DP_OK, hr );
2533 
2534     dwDataSize = 1024;
2535     hr = IDirectPlayX_GetPlayerName( pDP[0], dpid[0],
2536                                      lpData, &dwDataSize ); /* Local fetch */
2537     checkHR( DP_OK, hr );
2538     check( 50, dwDataSize );
2539     checkStr( "no_propagation_2", U1(*(LPDPNAME)lpData).lpszShortNameA );
2540 
2541     dwDataSize = 1024;
2542     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2543                                      lpData, &dwDataSize ); /* Remote fetch */
2544     checkHR( DP_OK, hr );
2545     check( 45, dwDataSize );
2546     checkStr( "player_name", U1(*(LPDPNAME)lpData).lpszShortNameA );
2547 
2548     /* - Remote (propagation, default) */
2549     U1(playerName).lpszShortNameA = (LPSTR) "propagation";
2550     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2551                                      DPSET_REMOTE );
2552     checkHR( DP_OK, hr );
2553 
2554     dwDataSize = 1024;
2555     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2556                                      lpData, &dwDataSize ); /* Remote fetch */
2557     checkHR( DP_OK, hr );
2558     check( 45, dwDataSize );
2559     checkStr( "propagation", U1(*(LPDPNAME)lpData).lpszShortNameA );
2560 
2561     /* -- 2 */
2562     U1(playerName).lpszShortNameA = (LPSTR) "propagation_2";
2563     hr = IDirectPlayX_SetPlayerName( pDP[0], dpid[0], &playerName,
2564                                      0 );
2565     checkHR( DP_OK, hr );
2566 
2567     dwDataSize = 1024;
2568     hr = IDirectPlayX_GetPlayerName( pDP[1], dpid[0],
2569                                      lpData, &dwDataSize ); /* Remote fetch */
2570     checkHR( DP_OK, hr );
2571     check( 47, dwDataSize );
2572     checkStr( "propagation_2", U1(*(LPDPNAME)lpData).lpszShortNameA );
2573 
2574 
2575     /* Checking system messages */
2576     check_messages( pDP[0], dpid, 2, &callbackData );
2577     checkStr( "S0,S0,S0,S0,S0,S0,S0,", callbackData.szTrace1 );
2578     checkStr( "48,28,57,28,57,57,59,", callbackData.szTrace2 );
2579     check_messages( pDP[1], dpid, 2, &callbackData );
2580     checkStr( "S1,S1,S1,S1,S1,S1,", callbackData.szTrace1 );
2581     checkStr( "28,57,28,57,57,59,", callbackData.szTrace2 );
2582 
2583 
2584     HeapFree( GetProcessHeap(), 0, lpData );
2585     IDirectPlayX_Release( pDP[0] );
2586     IDirectPlayX_Release( pDP[1] );
2587 
2588 }
2589 
2590 /* GetPlayerAccount */
2591 
2592 static BOOL CALLBACK EnumSessions_cb_join_secure( LPCDPSESSIONDESC2 lpThisSD,
2593                                                   LPDWORD lpdwTimeOut,
2594                                                   DWORD dwFlags,
2595                                                   LPVOID lpContext )
2596 {
2597     LPDIRECTPLAY4 pDP = (LPDIRECTPLAY4) lpContext;
2598     DPSESSIONDESC2 dpsd;
2599     DPCREDENTIALS dpCredentials;
2600     HRESULT hr;
2601 
2602     if (dwFlags & DPESC_TIMEDOUT)
2603     {
2604         return FALSE;
2605     }
2606 
2607     checkFlags( DPSESSION_SECURESERVER, lpThisSD->dwFlags, FLAGS_DPSESSION );
2608 
2609     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2610     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2611     dpsd.guidApplication = appGuid;
2612     dpsd.guidInstance = lpThisSD->guidInstance;
2613 
2614     ZeroMemory( &dpCredentials, sizeof(DPCREDENTIALS) );
2615     dpCredentials.dwSize = sizeof(DPCREDENTIALS);
2616     U1(dpCredentials).lpszUsernameA = (LPSTR) "user";
2617     U2(dpCredentials).lpszPasswordA = (LPSTR) "pass";
2618     hr = IDirectPlayX_SecureOpen( pDP, &dpsd, DPOPEN_JOIN,
2619                                   NULL, &dpCredentials );
2620     checkHR( DPERR_LOGONDENIED, hr ); /* TODO: Make this work */
2621 
2622     return TRUE;
2623 }
2624 
2625 static void test_GetPlayerAccount(void)
2626 {
2627 
2628     LPDIRECTPLAY4 pDP[2];
2629     DPSESSIONDESC2 dpsd;
2630     DPID dpid[2];
2631     HRESULT hr;
2632     UINT i;
2633 
2634     DWORD dwDataSize = 1024;
2635     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2636 
2637 
2638     for (i=0; i<2; i++)
2639     {
2640         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2641                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2642     }
2643     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2644     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2645     dpsd.guidApplication = appGuid;
2646     dpsd.dwMaxPlayers = 10;
2647 
2648     /* Uninitialized service provider */
2649     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0, lpData, &dwDataSize );
2650     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2651 
2652     if ( hr == DP_OK )
2653     {
2654         todo_wine win_skip( "GetPlayerAccount not implemented\n" );
2655         return;
2656     }
2657 
2658 
2659     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2660     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2661 
2662 
2663     /* No session */
2664     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0, lpData, &dwDataSize );
2665     checkHR( DPERR_NOSESSIONS, hr );
2666 
2667 
2668     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2669     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2670                                pDP[1], 0 );
2671 
2672     for (i=0; i<2; i++)
2673     {
2674         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL,
2675                                         0, 0 );
2676         checkHR( DP_OK, hr );
2677     }
2678 
2679 
2680     /* Session is not secure */
2681     dwDataSize = 1024;
2682     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2683                                         lpData, &dwDataSize );
2684     checkHR( DPERR_UNSUPPORTED, hr );
2685     check( 1024, dwDataSize );
2686 
2687 
2688     /* Open a secure session */
2689     for (i=0; i<2; i++)
2690     {
2691         hr = IDirectPlayX_Close( pDP[i] );
2692         checkHR( DP_OK, hr );
2693     }
2694 
2695     dpsd.dwFlags = DPSESSION_SECURESERVER;
2696     hr = IDirectPlayX_SecureOpen( pDP[0], &dpsd, DPOPEN_CREATE, NULL, NULL );
2697     checkHR( DP_OK, hr );
2698 
2699     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
2700                                     NULL, NULL, NULL, 0, 0 );
2701     checkHR( DP_OK, hr );
2702 
2703     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0,
2704                                     EnumSessions_cb_join_secure, pDP[1], 0 );
2705     checkHR( DP_OK, hr );
2706 
2707     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
2708                                     NULL, NULL, NULL, 0, 0 );
2709     checkHR( DPERR_INVALIDPARAMS, hr );
2710 
2711     /* TODO: Player creation so that this works */
2712 
2713     /* Invalid player */
2714     dwDataSize = 1024;
2715     hr = IDirectPlayX_GetPlayerAccount( pDP[0], 0, 0,
2716                                         lpData, &dwDataSize );
2717     checkHR( DPERR_INVALIDPLAYER, hr );
2718     check( 1024, dwDataSize );
2719 
2720     /* Invalid flags */
2721     dwDataSize = 1024;
2722     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], -1,
2723                                         lpData, &dwDataSize );
2724     checkHR( DPERR_INVALIDFLAGS, hr );
2725     check( 1024, dwDataSize );
2726 
2727     dwDataSize = 1024;
2728     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 1,
2729                                         lpData, &dwDataSize );
2730     checkHR( DPERR_INVALIDFLAGS, hr );
2731     check( 1024, dwDataSize );
2732 
2733     /* Small buffer */
2734     dwDataSize = 1024;
2735     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2736                                         NULL, &dwDataSize );
2737     checkHR( DPERR_INVALIDPLAYER, hr );
2738     check( 0, dwDataSize );
2739 
2740     dwDataSize = 0;
2741     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2742                                         lpData, &dwDataSize );
2743     checkHR( DPERR_INVALIDPLAYER, hr );
2744     check( 0, dwDataSize );
2745 
2746     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2747                                         lpData, &dwDataSize );
2748     checkHR( DPERR_INVALIDPLAYER, hr );
2749     check( 0, dwDataSize );
2750 
2751     /* Normal operation */
2752     dwDataSize = 1024;
2753     hr = IDirectPlayX_GetPlayerAccount( pDP[0], dpid[0], 0,
2754                                         lpData, &dwDataSize );
2755     checkHR( DPERR_INVALIDPLAYER, hr );
2756     check( 1024, dwDataSize );
2757 
2758 
2759     HeapFree( GetProcessHeap(), 0, lpData );
2760     IDirectPlayX_Release( pDP[0] );
2761     IDirectPlayX_Release( pDP[1] );
2762 
2763 }
2764 
2765 /* GetPlayerAddress */
2766 
2767 static BOOL CALLBACK EnumAddress_cb( REFGUID guidDataType,
2768                                      DWORD dwDataSize,
2769                                      LPCVOID lpData,
2770                                      LPVOID lpContext )
2771 {
2772     lpCallbackData callbackData = (lpCallbackData) lpContext;
2773     static REFGUID types[] = { &DPAID_TotalSize,
2774                                &DPAID_ServiceProvider,
2775                                &DPAID_INet,
2776                                &DPAID_INetW };
2777     static DWORD sizes[] = { 4, 16, 12, 24, 4, 16, 10, 20 };
2778 
2779 
2780     checkGuid( types[callbackData->dwCounter1%4], guidDataType );
2781     check( sizes[callbackData->dwCounter1], dwDataSize );
2782 
2783     switch(callbackData->dwCounter1)
2784     {
2785     case 0:
2786         check( 136, *(LPDWORD) lpData );
2787         break;
2788     case 4:
2789         check( 130, *(LPDWORD) lpData );
2790         break;
2791     case 1:
2792     case 5:
2793         checkGuid( &DPSPGUID_TCPIP, lpData );
2794         break;
2795     case 6:
2796         checkStr( "127.0.0.1", (LPSTR) lpData );
2797         break;
2798     default: break;
2799     }
2800 
2801 
2802     callbackData->dwCounter1++;
2803 
2804     return TRUE;
2805 }
2806 
2807 static void test_GetPlayerAddress(void)
2808 {
2809 
2810     LPDIRECTPLAY4 pDP[2];
2811     LPDIRECTPLAYLOBBY3 pDPL;
2812     DPSESSIONDESC2 dpsd;
2813     DPID dpid[2];
2814     CallbackData callbackData;
2815     HRESULT hr;
2816     UINT i;
2817 
2818     DWORD dwDataSize = 1024;
2819     LPVOID lpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
2820 
2821 
2822     for (i=0; i<2; i++)
2823     {
2824         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2825                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2826     }
2827     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2828     CoCreateInstance( &CLSID_DirectPlayLobby, NULL, CLSCTX_ALL,
2829                       &IID_IDirectPlayLobby3A, (LPVOID*) &pDPL );
2830 
2831 
2832     /* Uninitialized service provider */
2833     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0, lpData, &dwDataSize );
2834     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2835 
2836     if ( hr == DP_OK )
2837     {
2838         todo_wine win_skip( "GetPlayerAddress not implemented\n" );
2839         return;
2840     }
2841 
2842     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2843     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2844 
2845 
2846     /* No session */
2847     dwDataSize = 1024;
2848     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0, lpData, &dwDataSize );
2849     checkHR( DPERR_UNSUPPORTED, hr );
2850     check( 1024, dwDataSize );
2851 
2852     dwDataSize = 1024;
2853     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 1, lpData, &dwDataSize );
2854     checkHR( DPERR_INVALIDPLAYER, hr );
2855     check( 1024, dwDataSize );
2856 
2857 
2858     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2859     dpsd.guidApplication = appGuid;
2860     dpsd.dwMaxPlayers = 10;
2861     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2862     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2863                                pDP[1], 0 );
2864 
2865     for (i=0; i<2; i++)
2866     {
2867         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i], NULL, NULL, NULL,
2868                                         0, 0 );
2869         checkHR( DP_OK, hr );
2870     }
2871 
2872     /* Invalid player */
2873     dwDataSize = 1024;
2874     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 0,
2875                                         lpData, &dwDataSize );
2876     checkHR( DPERR_UNSUPPORTED, hr );
2877     check( 1024, dwDataSize );
2878 
2879     dwDataSize = 1024;
2880     hr = IDirectPlayX_GetPlayerAddress( pDP[0], 1,
2881                                         lpData, &dwDataSize );
2882     checkHR( DPERR_INVALIDPLAYER, hr );
2883     check( 1024, dwDataSize );
2884 
2885     /* Small buffer */
2886     dwDataSize = 1024;
2887     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2888                                         NULL, &dwDataSize );
2889     checkHR( DPERR_BUFFERTOOSMALL, hr );
2890     check( 136, dwDataSize );
2891 
2892     dwDataSize = 0;
2893     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2894                                         lpData, &dwDataSize );
2895     checkHR( DPERR_BUFFERTOOSMALL, hr );
2896     check( 136, dwDataSize );
2897 
2898     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2899                                         lpData, &dwDataSize );
2900     checkHR( DP_OK, hr );
2901     check( 136, dwDataSize );
2902 
2903 
2904     /* Regular parameters */
2905     callbackData.dwCounter1 = 0;
2906 
2907     /* - Local */
2908     dwDataSize = 1024;
2909     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[0],
2910                                         lpData, &dwDataSize );
2911     checkHR( DP_OK, hr );
2912     check( 136, dwDataSize );
2913 
2914     hr = IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb, lpData, dwDataSize,
2915                                        &callbackData );
2916     checkHR( DP_OK, hr );
2917 
2918     check( 4, callbackData.dwCounter1 );
2919 
2920     /* - Remote */
2921     dwDataSize = 1024;
2922     hr = IDirectPlayX_GetPlayerAddress( pDP[0], dpid[1],
2923                                         lpData, &dwDataSize );
2924     checkHR( DP_OK, hr );
2925     check( 130, dwDataSize );
2926 
2927     hr = IDirectPlayLobby_EnumAddress( pDPL, EnumAddress_cb, lpData, dwDataSize,
2928                                        &callbackData );
2929     checkHR( DP_OK, hr );
2930 
2931     check( 8, callbackData.dwCounter1 );
2932 
2933 
2934     HeapFree( GetProcessHeap(), 0, lpData );
2935     IDirectPlayX_Release( pDP[0] );
2936     IDirectPlayX_Release( pDP[1] );
2937 
2938 }
2939 
2940 /* GetPlayerFlags */
2941 
2942 static void test_GetPlayerFlags(void)
2943 {
2944 
2945     LPDIRECTPLAY4 pDP[2];
2946     DPSESSIONDESC2 dpsd;
2947     DPID dpid[4];
2948     HRESULT hr;
2949     UINT i;
2950 
2951     DWORD dwFlags = 0;
2952 
2953 
2954     for (i=0; i<2; i++)
2955     {
2956         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
2957                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
2958     }
2959     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
2960     dpsd.dwSize = sizeof(DPSESSIONDESC2);
2961     dpsd.guidApplication = appGuid;
2962     dpsd.dwMaxPlayers = 10;
2963 
2964     /* Uninitialized service provider */
2965     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
2966     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
2967 
2968     if ( hr == DP_OK )
2969     {
2970         todo_wine win_skip( "GetPlayerFlags not implemented\n" );
2971         return;
2972     }
2973 
2974     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
2975     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
2976 
2977 
2978     /* No session */
2979     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
2980     checkHR( DPERR_INVALIDPLAYER, hr );
2981 
2982     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 1, &dwFlags );
2983     checkHR( DPERR_INVALIDPLAYER, hr );
2984 
2985 
2986     IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
2987     IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
2988                                pDP[1], 0 );
2989 
2990     for (i=0; i<2; i++)
2991     {
2992         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
2993                                         NULL, NULL, NULL, 0, 0 );
2994         checkHR( DP_OK, hr );
2995     }
2996     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[2],
2997                                     NULL, NULL, NULL,
2998                                     0, DPPLAYER_SPECTATOR );
2999     checkHR( DP_OK, hr );
3000     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[3],
3001                                     NULL, NULL, NULL,
3002                                     0, DPPLAYER_SERVERPLAYER );
3003     checkHR( DP_OK, hr );
3004 
3005 
3006     /* Invalid player */
3007     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 0, &dwFlags );
3008     checkHR( DPERR_INVALIDPLAYER, hr );
3009 
3010     hr = IDirectPlayX_GetPlayerFlags( pDP[0], 2, &dwFlags );
3011     checkHR( DPERR_INVALIDPLAYER, hr );
3012 
3013     /* Invalid parameters */
3014     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[0], NULL );
3015     checkHR( DPERR_INVALIDPARAMS, hr );
3016 
3017 
3018     /* Regular parameters */
3019     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[0], &dwFlags );
3020     checkHR( DP_OK, hr );
3021     checkFlags( dwFlags, DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3022 
3023     hr = IDirectPlayX_GetPlayerFlags( pDP[1], dpid[1], &dwFlags );
3024     checkHR( DP_OK, hr );
3025     checkFlags( dwFlags, DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3026 
3027     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[1], &dwFlags );
3028     checkHR( DP_OK, hr );
3029     checkFlags( dwFlags, 0, FLAGS_DPPLAYER );
3030 
3031     hr = IDirectPlayX_GetPlayerFlags( pDP[0], dpid[2], &dwFlags );
3032     checkHR( DP_OK, hr );
3033     checkFlags( dwFlags, DPPLAYER_SPECTATOR | DPPLAYER_LOCAL, FLAGS_DPPLAYER );
3034 
3035     hr = IDirectPlayX_GetPlayerFlags( pDP[1], dpid[3], &dwFlags );
3036     checkHR( DP_OK, hr );
3037     checkFlags( dwFlags, DPPLAYER_SERVERPLAYER, FLAGS_DPPLAYER );
3038 
3039 
3040     IDirectPlayX_Release( pDP[0] );
3041     IDirectPlayX_Release( pDP[1] );
3042 
3043 }
3044 
3045 /* CreateGroup
3046    CreateGroupInGroup */
3047 
3048 static void test_CreateGroup(void)
3049 {
3050 
3051     LPDIRECTPLAY4 pDP;
3052     DPSESSIONDESC2 dpsd;
3053     DPID idFrom, idTo, dpid, idGroup, idGroupParent;
3054     DPNAME groupName;
3055     HRESULT hr;
3056     UINT i;
3057 
3058     LPCSTR lpData = "data";
3059     DWORD dwDataSize = strlen(lpData)+1;
3060     LPDPMSG_CREATEPLAYERORGROUP lpDataGet = HeapAlloc( GetProcessHeap(),
3061                                                        HEAP_ZERO_MEMORY,
3062                                                        1024 );
3063     DWORD dwDataSizeGet = 1024;
3064     CallbackData callbackData;
3065 
3066 
3067     CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3068                       &IID_IDirectPlay4A, (LPVOID*) &pDP );
3069     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
3070     dpsd.dwSize = sizeof(DPSESSIONDESC2);
3071     dpsd.guidApplication = appGuid;
3072     dpsd.dwMaxPlayers = 10;
3073     ZeroMemory( &groupName, sizeof(DPNAME) );
3074 
3075 
3076     /* No service provider */
3077     hr = IDirectPlayX_CreateGroup( pDP, &idGroup, NULL, NULL, 0, 0 );
3078     checkHR( DPERR_UNINITIALIZED, hr );
3079 
3080     hr = IDirectPlayX_CreateGroupInGroup( pDP, 0, &idGroup, NULL, NULL, 0, 0 );
3081     checkHR( DPERR_UNINITIALIZED, hr );
3082 
3083 
3084 
3085     init_TCPIP_provider( pDP, "127.0.0.1", 0 );
3086 
3087 
3088     /* No session */
3089     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3090                                    NULL, NULL, 0, 0 );
3091     todo_wine checkHR( DPERR_INVALIDPARAMS, hr );
3092 
3093     if ( hr == DPERR_UNINITIALIZED )
3094     {
3095         todo_wine win_skip( "CreateGroup not implemented\n" );
3096         return;
3097     }
3098 
3099     hr = IDirectPlayX_CreateGroupInGroup( pDP, 0, &idGroup,
3100                                           NULL, NULL, 0, 0 );
3101     checkHR( DPERR_INVALIDGROUP, hr );
3102 
3103     hr = IDirectPlayX_CreateGroupInGroup( pDP, 2, &idGroup,
3104                                           NULL, NULL, 0, 0 );
3105     checkHR( DPERR_INVALIDGROUP, hr );
3106 
3107 
3108     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3109     checkHR( DP_OK, hr );
3110     IDirectPlayX_CreatePlayer( pDP, &dpid,
3111                                NULL, NULL, NULL, 0, 0 );
3112 
3113 
3114 
3115     /* With name */
3116     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3117                                    NULL, NULL, 0, 0 );
3118     checkHR( DP_OK, hr );
3119 
3120     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3121                                           NULL, NULL, 0, 0 );
3122     checkHR( DP_OK, hr );
3123 
3124     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3125                                    &groupName, NULL, 0, 0 );
3126     checkHR( DP_OK, hr );
3127 
3128     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3129                                           &groupName, NULL, 0, 0 );
3130     checkHR( DP_OK, hr );
3131 
3132 
3133     groupName.dwSize = sizeof(DPNAME);
3134     U1(groupName).lpszShortNameA = (LPSTR) lpData;
3135 
3136 
3137     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3138                                    &groupName, NULL, 0, 0 );
3139     checkHR( DP_OK, hr );
3140 
3141     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3142                                           &groupName, NULL, 0, 0 );
3143     checkHR( DP_OK, hr );
3144 
3145 
3146     /* Message checking */
3147     for (i=0; i<6; i++)
3148     {
3149         dwDataSizeGet = 1024;
3150         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3151                                    &dwDataSizeGet );
3152         checkHR( DP_OK, hr );
3153         if ( NULL == U1(lpDataGet->dpnName).lpszShortNameA )
3154         {
3155             check( 48, dwDataSizeGet );
3156         }
3157         else
3158         {
3159             check( 48 + dwDataSize, dwDataSizeGet );
3160             checkStr( lpData, U1(lpDataGet->dpnName).lpszShortNameA );
3161         }
3162         check( DPID_SYSMSG, idFrom );
3163         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3164         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3165         checkFlags( DPGROUP_LOCAL,            lpDataGet->dwFlags, FLAGS_DPGROUP );
3166     }
3167     check_messages( pDP, &dpid, 1, &callbackData );
3168     checkStr( "", callbackData.szTrace1 );
3169 
3170 
3171     /* With data */
3172     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3173                                    NULL, (LPVOID) lpData, -1, 0 );
3174     checkHR( DPERR_INVALIDPARAMS, hr );
3175 
3176     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3177                                    NULL, (LPVOID) lpData, 0, 0 );
3178     checkHR( DP_OK, hr );
3179 
3180     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3181                                    NULL, NULL, dwDataSize, 0 );
3182     checkHR( DPERR_INVALIDPARAMS, hr );
3183 
3184     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3185                                    NULL, (LPVOID) lpData, dwDataSize, 0 );
3186     checkHR( DP_OK, hr );
3187 
3188 
3189     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3190                                           NULL, (LPVOID) lpData, -1, 0 );
3191     checkHR( DPERR_INVALIDPARAMS, hr );
3192 
3193     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3194                                           NULL, (LPVOID) lpData, 0, 0 );
3195     checkHR( DP_OK, hr );
3196 
3197     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3198                                           NULL, NULL, dwDataSize, 0 );
3199     checkHR( DPERR_INVALIDPARAMS, hr );
3200 
3201     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroup, &idGroup,
3202                                           NULL, (LPVOID)lpData, dwDataSize, 0 );
3203     checkHR( DP_OK, hr );
3204 
3205 
3206     hr = IDirectPlayX_CreateGroup( pDP, &idGroupParent,
3207                                    NULL, NULL, 0, 0 );
3208     checkHR( DP_OK, hr );
3209 
3210 
3211     /* Message checking */
3212     for (i=0; i<5; i++)
3213     {
3214         dwDataSizeGet = 1024;
3215         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3216                                    &dwDataSizeGet );
3217         checkHR( DP_OK, hr );
3218         check( 48 + lpDataGet->dwDataSize, dwDataSizeGet );
3219         check( DPID_SYSMSG, idFrom );
3220         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3221         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3222         checkFlags( DPGROUP_LOCAL,            lpDataGet->dwFlags, FLAGS_DPGROUP );
3223     }
3224     check_messages( pDP, &dpid, 1, &callbackData );
3225     checkStr( "", callbackData.szTrace1 );
3226 
3227 
3228     /* Flags and idGroupParent */
3229     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3230                                    NULL, NULL, 0, 0 );
3231     checkHR( DP_OK, hr );
3232 
3233     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3234                                    NULL, NULL, 0, DPGROUP_HIDDEN );
3235     checkHR( DP_OK, hr );
3236 
3237     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3238                                    NULL, NULL, 0, DPGROUP_STAGINGAREA );
3239     checkHR( DP_OK, hr );
3240 
3241     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3242                                    NULL, NULL, 0,
3243                                    DPGROUP_HIDDEN | DPGROUP_STAGINGAREA );
3244     checkHR( DP_OK, hr );
3245 
3246 
3247     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3248                                           NULL, NULL, 0, 0 );
3249     checkHR( DP_OK, hr );
3250 
3251     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3252                                           NULL, NULL, 0, DPGROUP_HIDDEN );
3253     checkHR( DP_OK, hr );
3254 
3255     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3256                                           NULL, NULL, 0, DPGROUP_STAGINGAREA );
3257     checkHR( DP_OK, hr );
3258 
3259     hr = IDirectPlayX_CreateGroupInGroup( pDP, idGroupParent, &idGroup,
3260                                           NULL, NULL, 0,
3261                                           DPGROUP_HIDDEN |
3262                                           DPGROUP_STAGINGAREA );
3263     checkHR( DP_OK, hr );
3264 
3265 
3266     /* Message checking */
3267     for (i=0; i<8; i++)
3268     {
3269         dwDataSizeGet = 1024;
3270         hr = IDirectPlayX_Receive( pDP, &idFrom, &idTo, 0, lpDataGet,
3271                                    &dwDataSizeGet );
3272         checkHR( DP_OK, hr );
3273         check( 48, dwDataSizeGet );
3274         check( DPID_SYSMSG, idFrom );
3275         checkConv( DPSYS_CREATEPLAYERORGROUP, lpDataGet->dwType, dpMsgType2str );
3276         check( DPPLAYERTYPE_GROUP,            lpDataGet->dwPlayerType );
3277 
3278         if ( lpDataGet->dpIdParent != 0 )
3279         {
3280             check( idGroupParent, lpDataGet->dpIdParent );
3281         }
3282 
3283         switch (i%4)
3284         {
3285         case 0:
3286             checkFlags( DPGROUP_LOCAL,
3287                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3288             break;
3289         case 1:
3290             checkFlags( DPGROUP_LOCAL | DPGROUP_HIDDEN,
3291                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3292             break;
3293         case 2:
3294             checkFlags( DPGROUP_STAGINGAREA | DPGROUP_LOCAL,
3295                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3296             break;
3297         case 3:
3298             checkFlags( DPGROUP_STAGINGAREA | DPGROUP_LOCAL | DPGROUP_HIDDEN,
3299                         lpDataGet->dwFlags, FLAGS_DPGROUP );
3300             break;
3301         default: break;
3302         }
3303     }
3304     check_messages( pDP, &dpid, 1, &callbackData );
3305     checkStr( "", callbackData.szTrace1 );
3306 
3307 
3308     /* If a group is created in C/S mode, no messages are sent */
3309 
3310     /* - Peer 2 peer */
3311     IDirectPlayX_Close( pDP );
3312 
3313     dpsd.dwFlags = 0;
3314     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3315     checkHR( DP_OK, hr );
3316     hr = IDirectPlayX_CreatePlayer( pDP, &dpid, NULL, NULL, NULL, 0, 0 );
3317     checkHR( DP_OK, hr );
3318 
3319     hr = IDirectPlayX_CreateGroup( pDP, &idGroup, NULL, NULL, 0, 0 );
3320     checkHR( DP_OK, hr );
3321 
3322     /* Messages are received */
3323     check_messages( pDP, &dpid, 1, &callbackData );
3324     checkStr( "S0,", callbackData.szTrace1 );
3325 
3326 
3327     /* - Client/Server */
3328     IDirectPlayX_Close( pDP );
3329 
3330     dpsd.dwFlags = DPSESSION_CLIENTSERVER;
3331     hr = IDirectPlayX_Open( pDP, &dpsd, DPOPEN_CREATE );
3332     checkHR( DP_OK, hr );
3333     hr = IDirectPlayX_CreatePlayer( pDP, &dpid,
3334                                     NULL, NULL, NULL, 0,
3335                                     DPPLAYER_SERVERPLAYER );
3336     checkHR( DP_OK, hr );
3337 
3338     hr = IDirectPlayX_CreateGroup( pDP, &idGroup,
3339                                    NULL, NULL, 0, 0 );
3340     checkHR( DP_OK, hr );
3341 
3342     /* No messages */
3343     check_messages( pDP, &dpid, 1, &callbackData );
3344     checkStr( "S0,", callbackData.szTrace1 ); /* Or at least there
3345                                                  shouldn't be messages... */
3346 
3347 
3348     HeapFree( GetProcessHeap(), 0, lpDataGet );
3349     IDirectPlayX_Release( pDP );
3350 
3351 }
3352 
3353 /* GroupOwner */
3354 
3355 static void test_GroupOwner(void)
3356 {
3357 
3358     LPDIRECTPLAY4 pDP[2];
3359     DPSESSIONDESC2 dpsd;
3360     DPID dpid[2], idGroup, idOwner;
3361     HRESULT hr;
3362     UINT i;
3363 
3364 
3365     for (i=0; i<2; i++)
3366     {
3367         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3368                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3369     }
3370     ZeroMemory( &dpsd, sizeof(DPSESSIONDESC2) );
3371     dpsd.dwSize = sizeof(DPSESSIONDESC2);
3372     dpsd.guidApplication = appGuid;
3373     dpsd.dwMaxPlayers = 10;
3374     idGroup = 0;
3375     idOwner = 0;
3376 
3377     /* Service provider not initialized */
3378     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3379     todo_wine checkHR( DPERR_UNINITIALIZED, hr );
3380     check( 0, idOwner );
3381 
3382     if ( hr == DP_OK )
3383     {
3384         todo_wine win_skip( "GetGroupOwner not implemented\n" );
3385         return;
3386     }
3387 
3388 
3389     for (i=0; i<2; i++)
3390         init_TCPIP_provider( pDP[i], "127.0.0.1", 0 );
3391 
3392     hr = IDirectPlayX_Open( pDP[0], &dpsd, DPOPEN_CREATE );
3393     checkHR( DP_OK, hr );
3394     hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd, 0, EnumSessions_cb_join,
3395                                     pDP[1], 0 );
3396     checkHR( DP_OK, hr );
3397 
3398     for (i=0; i<2; i++)
3399     {
3400         hr = IDirectPlayX_CreatePlayer( pDP[i], &dpid[i],
3401                                         NULL, NULL, NULL, 0, 0 );
3402         checkHR( DP_OK, hr );
3403     }
3404 
3405     /* Invalid group */
3406     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3407     checkHR( DPERR_INVALIDGROUP, hr );
3408 
3409     hr = IDirectPlayX_CreateGroup( pDP[0], &idGroup, NULL, NULL, 0, 0 );
3410     checkHR( DP_OK, hr );
3411 
3412     /* Fails, because we need a lobby session */
3413     hr = IDirectPlayX_GetGroupOwner( pDP[0], idGroup, &idOwner );
3414     checkHR( DPERR_UNSUPPORTED, hr );
3415 
3416 
3417     /* TODO:
3418      * - Make this work
3419      * - Check migration of the ownership of a group
3420      *   when the owner leaves
3421      */
3422 
3423 
3424     IDirectPlayX_Release( pDP[0] );
3425     IDirectPlayX_Release( pDP[1] );
3426 
3427 }
3428 
3429 /* EnumPlayers */
3430 
3431 static BOOL CALLBACK EnumPlayers_cb( DPID dpId,
3432                                      DWORD dwPlayerType,
3433                                      LPCDPNAME lpName,
3434                                      DWORD dwFlags,
3435                                      LPVOID lpContext )
3436 {
3437     lpCallbackData callbackData = (lpCallbackData) lpContext;
3438     char playerIndex = dpid2char( callbackData->dpid,
3439                                   callbackData->dpidSize,
3440                                   dpId );
3441 
3442 
3443     /* Trace to study player ids */
3444     callbackData->szTrace1[ callbackData->dwCounter1 ] = playerIndex;
3445     callbackData->dwCounter1++;
3446     callbackData->szTrace1[ callbackData->dwCounter1 ] = '\0';
3447 
3448     /* Trace to study flags received */
3449     strcat( callbackData->szTrace2,
3450             ( dwFlags2str(dwFlags, FLAGS_DPENUMPLAYERS) +
3451               strlen("DPENUMPLAYERS_") ) );
3452     strcat( callbackData->szTrace2, ":" );
3453 
3454 
3455     if ( playerIndex < '5' )
3456     {
3457         check( DPPLAYERTYPE_PLAYER, dwPlayerType );
3458     }
3459     else
3460     {
3461         check( DPPLAYERTYPE_GROUP, dwPlayerType );
3462     }
3463 
3464     return TRUE;
3465 
3466 }
3467 
3468 static BOOL CALLBACK EnumSessions_cb_EnumPlayers( LPCDPSESSIONDESC2 lpThisSD,
3469                                                   LPDWORD lpdwTimeOut,
3470                                                   DWORD dwFlags,
3471                                                   LPVOID lpContext )
3472 {
3473     lpCallbackData callbackData = (lpCallbackData) lpContext;
3474     HRESULT hr;
3475 
3476     if (dwFlags & DPESC_TIMEDOUT)
3477     {
3478         return FALSE;
3479     }
3480 
3481     /* guid = NULL */
3482     callbackData->dwCounter1 = 0;
3483     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, NULL, EnumPlayers_cb,
3484                                    &callbackData, 0 );
3485     checkHR( DPERR_NOSESSIONS, hr );
3486     check( 0, callbackData->dwCounter1 );
3487 
3488     /* guid = appGuid */
3489     callbackData->dwCounter1 = 0;
3490     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, (LPGUID) &appGuid,
3491                                    EnumPlayers_cb, &callbackData, 0 );
3492     checkHR( DPERR_NOSESSIONS, hr );
3493     check( 0, callbackData->dwCounter1 );
3494 
3495     callbackData->dwCounter1 = 0;
3496     hr = IDirectPlayX_EnumPlayers( callbackData->pDP, (LPGUID) &appGuid,
3497                                    EnumPlayers_cb, &callbackData,
3498                                    DPENUMPLAYERS_SESSION );
3499     checkHR( DPERR_NOSESSIONS, hr );
3500     check( 0, callbackData->dwCounter1 );
3501 
3502     /* guid = guidInstance */
3503     callbackData->dwCounter1 = 0;
3504     hr = IDirectPlayX_EnumPlayers( callbackData->pDP,
3505                                    (LPGUID) &lpThisSD->guidInstance,
3506                                    EnumPlayers_cb, &callbackData, 0 );
3507     checkHR( DPERR_NOSESSIONS, hr );
3508     check( 0, callbackData->dwCounter1 );
3509 
3510     callbackData->dwCounter1 = 0;
3511     hr = IDirectPlayX_EnumPlayers( callbackData->pDP,
3512                                    (LPGUID) &lpThisSD->guidInstance,
3513                                    EnumPlayers_cb, &callbackData,
3514                                    DPENUMPLAYERS_SESSION );
3515     checkHR( DPERR_GENERIC, hr ); /* Why? */
3516     check( 0, callbackData->dwCounter1 );
3517 
3518     return TRUE;
3519 
3520 }
3521 
3522 static void test_EnumPlayers(void)
3523 {
3524     LPDIRECTPLAY4 pDP[3];
3525     DPSESSIONDESC2 dpsd[3];
3526     DPID dpid[5+2]; /* 5 players, 2 groups */
3527     CallbackData callbackData;
3528     HRESULT hr;
3529     UINT i;
3530 
3531 
3532     for (i=0; i<3; i++)
3533     {
3534         CoCreateInstance( &CLSID_DirectPlay, NULL, CLSCTX_ALL,
3535                           &IID_IDirectPlay4A, (LPVOID*) &pDP[i] );
3536 
3537         ZeroMemory( &dpsd[i], sizeof(DPSESSIONDESC2) );
3538         dpsd[i].dwSize = sizeof(DPSESSIONDESC2);
3539     }
3540 
3541     dpsd[0].guidApplication = appGuid;
3542     dpsd[1].guidApplication = appGuid2;
3543     dpsd[2].guidApplication = GUID_NULL;
3544 
3545     callbackData.dpid = dpid;
3546     callbackData.dpidSize = 5+2;
3547 
3548 
3549     /* Uninitialized service provider */
3550     callbackData.dwCounter1 = 0;
3551     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, NULL,
3552                                    &callbackData, 0 );
3553     checkHR( DPERR_UNINITIALIZED, hr );
3554     check( 0, callbackData.dwCounter1 );
3555 
3556 
3557     init_TCPIP_provider( pDP[0], "127.0.0.1", 0 );
3558     init_TCPIP_provider( pDP[1], "127.0.0.1", 0 );
3559     init_TCPIP_provider( pDP[2], "127.0.0.1", 0 );
3560 
3561 
3562     /* No session */
3563     callbackData.dwCounter1 = 0;
3564     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3565                                    &callbackData, 0 );
3566     todo_wine checkHR( DPERR_NOSESSIONS, hr );
3567     check( 0, callbackData.dwCounter1 );
3568 
3569     if ( hr == DPERR_UNINITIALIZED )
3570     {
3571         todo_wine win_skip( "EnumPlayers not implemented\n" );
3572         return;
3573     }
3574 
3575     callbackData.dwCounter1 = 0;
3576     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3577                                    &callbackData, 0 );
3578     checkHR( DPERR_NOSESSIONS, hr );
3579     check( 0, callbackData.dwCounter1 );
3580 
3581     callbackData.dwCounter1 = 0;
3582     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3583                                    &callbackData, DPENUMPLAYERS_SESSION );
3584     checkHR( DPERR_NOSESSIONS, hr );
3585     check( 0, callbackData.dwCounter1 );
3586 
3587 
3588     hr = IDirectPlayX_Open( pDP[0], &dpsd[0], DPOPEN_CREATE );
3589     checkHR( DP_OK, hr );
3590     hr = IDirectPlayX_Open( pDP[1], &dpsd[1], DPOPEN_CREATE );
3591     checkHR( DP_OK, hr );
3592 
3593 
3594     /* No players */
3595     callbackData.dwCounter1 = 0;
3596     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3597                                    &callbackData, 0 );
3598     checkHR( DP_OK, hr );
3599     check( 0, callbackData.dwCounter1 );
3600 
3601 
3602     /* Create players */
3603     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[0],
3604                                     NULL, NULL, NULL, 0,
3605                                     DPPLAYER_SERVERPLAYER );
3606     checkHR( DP_OK, hr );
3607     hr = IDirectPlayX_CreatePlayer( pDP[1], &dpid[1],
3608                                     NULL, NULL, NULL, 0,
3609                                     0 );
3610     checkHR( DP_OK, hr );
3611 
3612     hr = IDirectPlayX_CreatePlayer( pDP[0], &dpid[2],
3613                                     NULL, NULL, NULL, 0,
3614                                     0 );
3615     checkHR( DP_OK, hr );
3616     hr = IDirectPlayX_CreateGroup( pDP[0], &dpid[5],
3617                                    NULL, NULL, 0, 0 );
3618     checkHR( DP_OK, hr );
3619 
3620 
3621     /* Invalid parameters */
3622     callbackData.dwCounter1 = 0;
3623     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, NULL,
3624                                    &callbackData, 0 );
3625     checkHR( DPERR_INVALIDPARAMS, hr );
3626     check( 0, callbackData.dwCounter1 );
3627 
3628     callbackData.dwCounter1 = 0;
3629     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3630                                    &callbackData, DPENUMPLAYERS_SESSION );
3631     checkHR( DPERR_INVALIDPARAMS, hr );
3632     check( 0, callbackData.dwCounter1 );
3633 
3634 
3635     /* Regular operation */
3636     callbackData.dwCounter1 = 0;
3637     callbackData.szTrace2[0] = 0;
3638     hr = IDirectPlayX_EnumPlayers( pDP[0], NULL, EnumPlayers_cb,
3639                                    &callbackData, 0 );
3640     checkHR( DP_OK, hr );
3641     check( 2, callbackData.dwCounter1 );
3642     checkStr( "20", callbackData.szTrace1 );
3643     checkStr( "ALL:SERVERPLAYER:", callbackData.szTrace2 );
3644 
3645     callbackData.dwCounter1 = 0;
3646     callbackData.szTrace2[0] = 0;
3647     hr = IDirectPlayX_EnumPlayers( pDP[1], NULL, EnumPlayers_cb,
3648                                    &callbackData, 0 );
3649     checkHR( DP_OK, hr );
3650     check( 1, callbackData.dwCounter1 );
3651     checkStr( "1", callbackData.szTrace1 );
3652     checkStr( "ALL:", callbackData.szTrace2 );
3653 
3654     callbackData.dwCounter1 = 0;
3655     callbackData.szTrace2[0] = 0;
3656     hr = IDirectPlayX_EnumPlayers( pDP[0], (LPGUID) &appGuid, EnumPlayers_cb,
3657                                    &callbackData, 0 );
3658     checkHR( DP_OK, hr );
3659     check( 2, callbackData.dwCounter1 ); /* Guid is ignored */
3660     checkStr( "20", callbackData.szTrace1 );
3661     checkStr( "ALL:SERVERPLAYER:", callbackData.szTrace2 );
3662 
3663 
3664     /* Enumerating from a remote session */
3665     /* - Session not open */
3666     callbackData.pDP = pDP[2];
3667     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[2], 0,
3668                                     EnumSessions_cb_EnumPlayers,
3669                                     &callbackData, 0 );
3670     checkHR( DP_OK, hr );
3671 
3672 
3673     /* - Open session */
3674     callbackData.pDP = pDP[2];
3675     hr = IDirectPlayX_EnumSessions( pDP[2], &dpsd[0], 0, EnumSessions_cb_join,
3676                                     pDP[2], 0 );
3677     checkHR( DP_OK, hr );
3678     hr = IDirectPlayX_CreatePlayer( pDP[2], &dpid[3],
3679                                     NULL, NULL, NULL, 0,
3680                                     DPPLAYER_SPECTATOR );
3681     checkHR( DP_OK, hr );
3682     hr = IDirectPlayX_CreatePlayer( pDP[2], &dpid[4],
3683                                     NULL, NULL, NULL, 0,
3684                                     0 );
3685     checkHR( DP_OK, hr );
3686     hr = IDirectPlayX_CreateGroup( pDP[2], &dpid[6],
3687                                    NULL, NULL, 0, 0 );
3688     checkHR( DP_OK, hr );
3689 
3690     callbackData.dwCounter1 = 0;
3691     callbackData.szTrace2[0] = 0;
3692     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3693                                    &callbackData, 0 );
3694     checkHR( DP_OK, hr );
3695     check( 4, callbackData.dwCounter1 );
3696     checkStr( "4302", callbackData.szTrace1 );
3697     checkStr( "ALL:SPECTATOR:SERVERPLAYER:ALL:", callbackData.szTrace2 );
3698 
3699 
3700     /* Flag tests */
3701 
3702     callbackData.dwCounter1 = 0;
3703     callbackData.szTrace2[0] = 0;
3704     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3705                                    &callbackData, DPENUMPLAYERS_ALL );
3706     checkHR( DP_OK, hr );
3707     check( 4, callbackData.dwCounter1 );
3708     checkStr( "4302", callbackData.szTrace1 );
3709     checkStr( "ALL:SPECTATOR:SERVERPLAYER:ALL:", callbackData.szTrace2 );
3710 
3711     callbackData.dwCounter1 = 0;
3712     callbackData.szTrace2[0] = 0;
3713     hr = IDirectPlayX_EnumPlayers( pDP[2], NULL, EnumPlayers_cb,
3714                                    &callbackData, DPENUMPLAYERS_GROUP );
3715     checkHR( DP_OK, hr );
3716     check( 6, callbackData.dwCounter1 );
3717     checkStr( "430256", callbackData.szTrace1 );
3718     checkStr( "GROUP:"
3719               "GROUP,DPENUMPLAYERS_SPECTATOR:"
3720               "GROUP,DPENUMPLAYERS_SERVERPLAYER:"
3721               "GROUP:ALL:ALL:", callbackData.szTrace2 );
3722 
3723     callbackData.dwCounter1 = 0;
3724     callbackData.szTrace2[0] = 0;
3725     hr =