Release 980726
[wine/multimedia.git] / multimedia / dplay.c
blobeef3542f4abbb6d9645d2978c30f00773f4b44fd
1 /* Direct Play 3 and Direct Play Lobby 1 Implementation
2 * Presently only the Lobby skeleton is implemented.
4 * Copyright 1998 - Peter Hunnisett
6 */
7 #include "windows.h"
8 #include "heap.h"
9 #include "wintypes.h"
10 #include "winerror.h"
11 #include "interfaces.h"
12 #include "mmsystem.h"
13 #include "dplay.h"
14 #include "debug.h"
15 #include "winnt.h"
16 #include "winreg.h"
19 static HRESULT WINAPI IDirectPlayLobby_QueryInterface
20 ( LPDIRECTPLAYLOBBY2 this,
21 REFIID riid,
22 LPVOID* ppvObj )
24 FIXME( dplay, ":stub\n");
25 return DPERR_OUTOFMEMORY;
28 static ULONG WINAPI IDirectPlayLobby_AddRef
29 ( LPDIRECTPLAYLOBBY2 this )
31 ++(this->ref);
32 TRACE( dplay," ref count now %ld\n", this->ref );
33 return (this->ref);
36 static ULONG WINAPI IDirectPlayLobby_Release
37 ( LPDIRECTPLAYLOBBY2 this )
39 this->ref--;
41 TRACE( dplay, " ref count now %ld\n", this->ref );
43 /* Deallocate if this is the last reference to the object */
44 if( !(this->ref) )
46 HeapFree( GetProcessHeap(), 0, this );
47 return 0;
50 return this->ref;
53 /********************************************************************
55 * Connects an application to the session specified by the DPLCONNECTION
56 * structure currently stored with the DirectPlayLobby object.
58 * Returns a IDirectPlay2 or IDirectPlay2A interface.
61 static HRESULT WINAPI IDirectPlayLobby_Connect
62 ( LPDIRECTPLAYLOBBY2 this,
63 DWORD dwFlags,
64 LPDIRECTPLAY2* lplpDP,
65 IUnknown* pUnk)
67 FIXME( dplay, ":stub\n");
68 return DPERR_OUTOFMEMORY;
71 /********************************************************************
73 * Creates a DirectPlay Address, given a service provider-specific network
74 * address.
75 * Returns an address contains the globally unique identifier
76 * (GUID) of the service provider and data that the service provider can
77 * interpret as a network address.
80 static HRESULT WINAPI IDirectPlayLobby_CreateAddress
81 ( LPDIRECTPLAYLOBBY2 this,
82 REFGUID guidSP,
83 REFGUID guidDataType,
84 LPCVOID lpData,
85 DWORD dwDataSize,
86 LPVOID lpAddress,
87 LPDWORD lpdwAddressSize )
89 FIXME( dplay, ":stub\n");
90 return DPERR_OUTOFMEMORY;
93 /********************************************************************
95 * Parses out chunks from the DirectPlay Address buffer by calling the
96 * given callback function, with lpContext, for each of the chunks.
99 static HRESULT WINAPI IDirectPlayLobby_EnumAddress
100 ( LPDIRECTPLAYLOBBY2 this,
101 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
102 LPCVOID lpAddress,
103 DWORD dwAddressSize,
104 LPVOID lpContext )
106 FIXME( dplay, ":stub\n");
107 return DPERR_OUTOFMEMORY;
110 /********************************************************************
112 * Enumerates all the address types that a given service provider needs to
113 * build the DirectPlay Address.
116 static HRESULT WINAPI IDirectPlayLobby_EnumAddressTypes
117 ( LPDIRECTPLAYLOBBY2 this,
118 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
119 REFGUID guidSP,
120 LPVOID lpContext,
121 DWORD dwFlags )
123 FIXME( dplay, ":stub\n");
124 return DPERR_OUTOFMEMORY;
127 /********************************************************************
129 * Enumerates what applications are registered with DirectPlay by
130 * invoking the callback function with lpContext.
133 static HRESULT WINAPI IDirectPlayLobby_EnumLocalApplications
134 ( LPDIRECTPLAYLOBBY2 this,
135 LPDPLENUMLOCALAPPLICATIONSCALLBACK a,
136 LPVOID lpContext,
137 DWORD dwFlags )
139 FIXME( dplay, ":stub\n");
140 return DPERR_OUTOFMEMORY;
143 /********************************************************************
145 * Retrieves the DPLCONNECTION structure that contains all the information
146 * needed to start and connect an application. This was generated using
147 * either the RunApplication or SetConnectionSettings methods.
149 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows
150 * the data structure to be allocated by our caller which can then
151 * call this procedure/method again with a valid data pointer.
153 static HRESULT WINAPI IDirectPlayLobby_GetConnectionSettings
154 ( LPDIRECTPLAYLOBBY2 this,
155 DWORD dwAppID,
156 LPVOID lpData,
157 LPDWORD lpdwDataSize )
159 LPDPLCONNECTION lpConnectionSettings;
161 FIXME( dplay, ":semi stub %p %08lx %p %p \n", this, dwAppID, lpData, lpdwDataSize );
163 if ( !lpData )
165 /* Let's check the size of the buffer that the application has allocated */
166 if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
168 return DP_OK;
170 else
172 *lpdwDataSize = sizeof( DPLCONNECTION );
173 return DPERR_BUFFERTOOSMALL;
177 /* Ok we assume that we've been given a buffer that is large enough for our needs */
178 lpConnectionSettings = ( LPDPLCONNECTION ) lpData;
180 /* Fill in the fields */
182 return DPERR_NOTLOBBIED;
185 /********************************************************************
187 * Retrieves the message sent between a lobby client and a DirectPlay
188 * application. All messages are queued until received.
191 static HRESULT WINAPI IDirectPlayLobby_ReceiveLobbyMessage
192 ( LPDIRECTPLAYLOBBY2 this,
193 DWORD dwFlags,
194 DWORD dwAppID,
195 LPDWORD lpdwMessageFlags,
196 LPVOID lpData,
197 LPDWORD lpdwDataSize )
199 FIXME( dplay, ":stub %p %08lx %08lx %p %p %p\n", this, dwFlags, dwAppID, lpdwMessageFlags, lpData,
200 lpdwDataSize );
201 return DPERR_OUTOFMEMORY;
204 /********************************************************************
206 * Starts an application and passes to it all the information to
207 * connect to a session.
210 static HRESULT WINAPI IDirectPlayLobby_RunApplication
211 ( LPDIRECTPLAYLOBBY2 this,
212 DWORD dwFlags,
213 LPDWORD lpdwAppID,
214 LPDPLCONNECTION lpConn,
215 HANDLE32 hReceiveEvent )
217 FIXME( dplay, ":stub\n");
218 return DPERR_OUTOFMEMORY;
221 /********************************************************************
223 * Sends a message between the application and the lobby client.
224 * All messages are queued until received.
227 static HRESULT WINAPI IDirectPlayLobby_SendLobbyMessage
228 ( LPDIRECTPLAYLOBBY2 this,
229 DWORD dwFlags,
230 DWORD dwAppID,
231 LPVOID lpData,
232 DWORD dwDataSize )
234 FIXME( dplay, ":stub\n");
235 return DPERR_OUTOFMEMORY;
238 /********************************************************************
240 * Modifies the DPLCONNECTION structure to contain all information
241 * needed to start and connect an application.
244 static HRESULT WINAPI IDirectPlayLobby_SetConnectionSettings
245 ( LPDIRECTPLAYLOBBY2 this,
246 DWORD dwFlags,
247 DWORD dwAppID,
248 LPDPLCONNECTION lpConn )
250 FIXME( dplay, ": this=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p: stub\n",
251 this, dwFlags, dwAppID, lpConn );
253 /* Paramater check */
254 if( dwFlags || !this || !lpConn )
256 return DPERR_INVALIDPARAMS;
259 if( !( lpConn->dwSize == sizeof(DPLCONNECTION) ) )
261 /* Is this the right return code? */
262 return DPERR_INVALIDPARAMS;
265 return DPERR_OUTOFMEMORY;
268 /********************************************************************
270 * Registers an event that will be set when a lobby message is received.
273 static HRESULT WINAPI IDirectPlayLobby_SetLobbyMessageEvent
274 ( LPDIRECTPLAYLOBBY2 this,
275 DWORD dwFlags,
276 DWORD dwAppID,
277 HANDLE32 hReceiveEvent )
279 FIXME( dplay, ":stub\n");
280 return DPERR_OUTOFMEMORY;
283 static HRESULT WINAPI IDirectPlayLobby_CreateCompoundAddress
284 ( LPDIRECTPLAYLOBBY2 this,
285 LPCDPCOMPOUNDADDRESSELEMENT lpElements,
286 DWORD dwElementCount,
287 LPVOID lpAddress,
288 LPDWORD lpdwAddressSize )
290 FIXME( dplay, ":stub\n");
291 return DPERR_OUTOFMEMORY;
294 /* Direct Play Lobby 2 Virtual Table for methods */
295 static struct tagLPDIRECTPLAYLOBBY2_VTABLE lobby2VT = {
296 IDirectPlayLobby_QueryInterface,
297 IDirectPlayLobby_AddRef,
298 IDirectPlayLobby_Release,
299 IDirectPlayLobby_Connect,
300 IDirectPlayLobby_CreateAddress,
301 IDirectPlayLobby_EnumAddress,
302 IDirectPlayLobby_EnumAddressTypes,
303 IDirectPlayLobby_EnumLocalApplications,
304 IDirectPlayLobby_GetConnectionSettings,
305 IDirectPlayLobby_ReceiveLobbyMessage,
306 IDirectPlayLobby_RunApplication,
307 IDirectPlayLobby_SendLobbyMessage,
308 IDirectPlayLobby_SetConnectionSettings,
309 IDirectPlayLobby_SetLobbyMessageEvent,
310 IDirectPlayLobby_CreateCompoundAddress
313 /***************************************************************************
314 * DirectPlayLobbyCreateA (DPLAYX.4)
317 HRESULT WINAPI DirectPlayLobbyCreateA( LPGUID lpGUIDDSP,
318 LPDIRECTPLAYLOBBY2A *lplpDPL,
319 IUnknown *lpUnk,
320 LPVOID lpData,
321 DWORD dwDataSize )
323 TRACE(dplay,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
324 lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
326 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
327 * equal 0. These fields are mostly for future expansion.
329 if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
331 *lplpDPL = NULL;
332 return DPERR_INVALIDPARAMS;
335 *lplpDPL = (LPDIRECTPLAYLOBBY2A)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
336 sizeof( IDirectPlayLobby2A ) );
338 if( ! (*lplpDPL) )
340 return DPERR_OUTOFMEMORY;
343 (*lplpDPL)->lpvtbl = &lobby2VT;
344 (*lplpDPL)->ref = 1;
346 /* Still some stuff to do here */
348 return DP_OK;
351 /***************************************************************************
352 * DirectPlayLobbyCreateW (DPLAYX.5)
355 HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP,
356 LPDIRECTPLAYLOBBY2 *lplpDPL,
357 IUnknown *lpUnk,
358 LPVOID lpData,
359 DWORD dwDataSize )
361 TRACE(dplay,"lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
362 lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
364 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
365 * equal 0. These fields are mostly for future expansion.
367 if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
369 *lplpDPL = NULL;
370 return DPERR_INVALIDPARAMS;
373 *lplpDPL = (LPDIRECTPLAYLOBBY2)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
374 sizeof( IDirectPlayLobby2 ) );
376 if( !*lplpDPL)
378 return DPERR_OUTOFMEMORY;
381 (*lplpDPL)->lpvtbl = &lobby2VT;
382 (*lplpDPL)->ref = 1;
384 return DP_OK;
388 /***************************************************************************
389 * DirectPlayEnumerateA (DPLAYX.2)
391 * The pointer to the structure lpContext will be filled with the
392 * appropriate data for each service offered by the OS. These services are
393 * not necessarily available on this particular machine but are defined
394 * as simple service providers under the "Service Providers" registry key.
395 * This structure is then passed to lpEnumCallback for each of the different
396 * services.
398 * This API is useful only for applications written using DirectX3 or
399 * worse. It is superceeded by IDirectPlay3::EnumConnections which also
400 * gives information on the actual connections.
402 * defn of a service provider:
403 * A dynamic-link library used by DirectPlay to communicate over a network.
404 * The service provider contains all the network-specific code required
405 * to send and receive messages. Online services and network operators can
406 * supply service providers to use specialized hardware, protocols, communications
407 * media, and network resources.
409 * TODO: Allocate string buffer space from the heap (length from reg)
410 * Pass real device driver numbers...
411 * Get the GUID properly...
413 HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
414 LPVOID lpContext )
417 HKEY hkResult;
418 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
419 LPSTR guidDataSubKey = "Guid";
420 LPSTR majVerDataSubKey = "dwReserved1";
421 DWORD dwIndex, sizeOfSubKeyName=50;
422 char subKeyName[51];
424 TRACE( dplay, ": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
426 if( !lpEnumCallback || !*lpEnumCallback )
428 return DPERR_INVALIDPARAMS;
431 /* Need to loop over the service providers in the registry */
432 if( RegOpenKeyEx32A( HKEY_LOCAL_MACHINE, searchSubKey,
433 0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
435 /* Hmmm. Does this mean that there are no service providers? */
436 ERR(dplay, ": no service providers?\n");
437 return DP_OK;
440 /* Traverse all the service providers we have available */
441 for( dwIndex=0;
442 RegEnumKey32A( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) !=
443 ERROR_NO_MORE_ITEMS;
444 ++dwIndex )
446 HKEY hkServiceProvider;
447 GUID serviceProviderGUID;
448 DWORD returnTypeGUID, returnTypeReserved1, sizeOfReturnBuffer=50;
449 char returnBuffer[51];
450 DWORD majVersionNum, minVersionNum;
451 LPWSTR lpWGUIDString;
453 TRACE( dplay, " this time through: %s\n", subKeyName );
455 /* Get a handle for this particular service provider */
456 if( RegOpenKeyEx32A( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
457 &hkServiceProvider ) != ERROR_SUCCESS )
459 ERR( dplay, ": what the heck is going on?\n" );
460 continue;
463 /* Get the GUID, Device major number and device minor number
464 * from the registry.
466 if( RegQueryValueEx32A( hkServiceProvider, guidDataSubKey,
467 NULL, &returnTypeGUID, returnBuffer,
468 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
470 ERR( dplay, ": missing GUID registry data members\n" );
471 continue;
474 /* FIXME: Check return types to ensure we're interpreting data right */
475 lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
476 CLSIDFromString32( (LPCOLESTR32)lpWGUIDString, &serviceProviderGUID );
477 HeapFree( GetProcessHeap(), 0, lpWGUIDString );
479 sizeOfReturnBuffer = 50;
481 if( RegQueryValueEx32A( hkServiceProvider, majVerDataSubKey,
482 NULL, &returnTypeReserved1, returnBuffer,
483 &sizeOfReturnBuffer ) != ERROR_SUCCESS )
485 ERR( dplay, ": missing dwReserved1 registry data members\n") ;
486 continue;
488 /* FIXME: This couldn't possibly be right...*/
489 majVersionNum = GET_DWORD( returnBuffer );
491 /* The enumeration will return FALSE if we are not to continue */
492 if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
493 majVersionNum, (DWORD)0, lpContext ) )
495 WARN( dplay, "lpEnumCallback returning FALSE\n" );
496 break;
500 return DP_OK;
504 /***************************************************************************
505 * DirectPlayEnumerateW (DPLAYX.3)
508 HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
511 FIXME( dplay, ":stub\n");
513 return DPERR_OUTOFMEMORY;
517 /***************************************************************************
518 * DirectPlayCreate (DPLAYX.1) (DPLAY.1)
521 HRESULT WINAPI DirectPlayCreate
522 ( LPGUID lpGUID, LPDIRECTPLAY *lplpDP, IUnknown *pUnk)
525 FIXME( dplay, ":stub\n");
526 return DPERR_OUTOFMEMORY;