📄 dplobby.c
字号:
return E_NOINTERFACE;
}
IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBY)*ppvObj );
return S_OK;
}
/*
* Simple procedure. Just increment the reference count to this
* structure and return the new reference count.
*/
static ULONG WINAPI DPL_AddRef
( LPDIRECTPLAYLOBBY iface )
{
ULONG ulInterfaceRefCount, ulObjRefCount;
IDirectPlayLobbyWImpl *This = (IDirectPlayLobbyWImpl *)iface;
ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef );
ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
TRACE( "ref count incremented to %lu:%lu for %p\n",
ulInterfaceRefCount, ulObjRefCount, This );
return ulObjRefCount;
}
/*
* Simple COM procedure. Decrease the reference count to this object.
* If the object no longer has any reference counts, free up the associated
* memory.
*/
static ULONG WINAPI DPL_Release
( LPDIRECTPLAYLOBBYA iface )
{
ULONG ulInterfaceRefCount, ulObjRefCount;
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef );
ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
TRACE( "ref count decremented to %lu:%lu for %p\n",
ulInterfaceRefCount, ulObjRefCount, This );
/* Deallocate if this is the last reference to the object */
if( ulObjRefCount == 0 )
{
DPL_DestroyLobby3( This );
DPL_DestroyLobby2( This );
DPL_DestroyLobby1( This );
DPL_DestroyIUnknown( This );
}
if( ulInterfaceRefCount == 0 )
{
HeapFree( GetProcessHeap(), 0, This );
}
return ulInterfaceRefCount;
}
/********************************************************************
*
* Connects an application to the session specified by the DPLCONNECTION
* structure currently stored with the DirectPlayLobby object.
*
* Returns an IDirectPlay interface.
*
*/
static HRESULT WINAPI DPL_ConnectEx
( IDirectPlayLobbyAImpl* This,
DWORD dwFlags,
REFIID riid,
LPVOID* lplpDP,
IUnknown* pUnk)
{
HRESULT hr;
DWORD dwOpenFlags = 0;
DWORD dwConnSize = 0;
LPDPLCONNECTION lpConn;
FIXME("(%p)->(0x%08lx,%p,%p): semi stub\n", This, dwFlags, lplpDP, pUnk );
if( pUnk )
{
return DPERR_INVALIDPARAMS;
}
/* Backwards compatibility */
if( dwFlags == 0 )
{
dwFlags = DPCONNECT_RETURNSTATUS;
}
/* Create the DirectPlay interface */
if( ( hr = DP_CreateInterface( riid, lplpDP ) ) != DP_OK )
{
ERR( "error creating interface for %s:%s.\n",
debugstr_guid( riid ), DPLAYX_HresultToString( hr ) );
return hr;
}
/* FIXME: Is it safe/correct to use appID of 0? */
hr = IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY)This,
0, NULL, &dwConnSize );
if( hr != DPERR_BUFFERTOOSMALL )
{
return hr;
}
lpConn = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwConnSize );
if( lpConn == NULL )
{
return DPERR_NOMEMORY;
}
/* FIXME: Is it safe/correct to use appID of 0? */
hr = IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY)This,
0, lpConn, &dwConnSize );
if( FAILED( hr ) )
{
HeapFree( GetProcessHeap(), 0, lpConn );
return hr;
}
#if 0
/* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
* - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
* - Call IDirectPlay::InitializeConnection
*/
/* Now initialize the Service Provider */
hr = IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2*)lplpDP),
#endif
/* Setup flags to pass into DirectPlay::Open */
if( dwFlags & DPCONNECT_RETURNSTATUS )
{
dwOpenFlags |= DPOPEN_RETURNSTATUS;
}
dwOpenFlags |= lpConn->dwFlags;
hr = IDirectPlayX_Open( (*(LPDIRECTPLAY2*)lplpDP), lpConn->lpSessionDesc,
dwOpenFlags );
HeapFree( GetProcessHeap(), 0, lpConn );
return hr;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
LPDIRECTPLAY2A* lplpDP,
IUnknown* pUnk)
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
return DPL_ConnectEx( This, dwFlags, &IID_IDirectPlay2A,
(LPVOID)lplpDP, pUnk );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
LPDIRECTPLAY2* lplpDP,
IUnknown* pUnk)
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface; /* Yes cast to A */
return DPL_ConnectEx( This, dwFlags, &IID_IDirectPlay2,
(LPVOID)lplpDP, pUnk );
}
/********************************************************************
*
* Creates a DirectPlay Address, given a service provider-specific network
* address.
* Returns an address contains the globally unique identifier
* (GUID) of the service provider and data that the service provider can
* interpret as a network address.
*
* NOTE: It appears that this method is supposed to be really really stupid
* with no error checking on the contents.
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
( LPDIRECTPLAYLOBBYA iface,
REFGUID guidSP,
REFGUID guidDataType,
LPCVOID lpData,
DWORD dwDataSize,
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize,
lpAddress, lpdwAddressSize, TRUE );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
( LPDIRECTPLAYLOBBY iface,
REFGUID guidSP,
REFGUID guidDataType,
LPCVOID lpData,
DWORD dwDataSize,
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize,
lpAddress, lpdwAddressSize, FALSE );
}
HRESULT DPL_CreateAddress(
REFGUID guidSP,
REFGUID guidDataType,
LPCVOID lpData,
DWORD dwDataSize,
LPVOID lpAddress,
LPDWORD lpdwAddressSize,
BOOL bAnsiInterface )
{
const DWORD dwNumAddElements = 2; /* Service Provide & address data type */
DPCOMPOUNDADDRESSELEMENT addressElements[ 2 /* dwNumAddElements */ ];
TRACE( "(%p)->(%p,%p,0x%08lx,%p,%p,%d)\n", guidSP, guidDataType, lpData, dwDataSize,
lpAddress, lpdwAddressSize, bAnsiInterface );
addressElements[ 0 ].guidDataType = DPAID_ServiceProvider;
addressElements[ 0 ].dwDataSize = sizeof( GUID );
addressElements[ 0 ].lpData = (LPVOID)guidSP;
addressElements[ 1 ].guidDataType = *guidDataType;
addressElements[ 1 ].dwDataSize = dwDataSize;
addressElements[ 1 ].lpData = (LPVOID)lpData;
/* Call CreateCompoundAddress to cut down on code.
NOTE: We can do this because we don't support DPL 1 interfaces! */
return DPL_CreateCompoundAddress( addressElements, dwNumAddElements,
lpAddress, lpdwAddressSize, bAnsiInterface );
}
/********************************************************************
*
* Parses out chunks from the DirectPlay Address buffer by calling the
* given callback function, with lpContext, for each of the chunks.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
( LPDIRECTPLAYLOBBYA iface,
LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
LPCVOID lpAddress,
DWORD dwAddressSize,
LPVOID lpContext )
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This, lpEnumAddressCallback, lpAddress,
dwAddressSize, lpContext );
return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
( LPDIRECTPLAYLOBBY iface,
LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
LPCVOID lpAddress,
DWORD dwAddressSize,
LPVOID lpContext )
{
IDirectPlayLobbyWImpl *This = (IDirectPlayLobbyWImpl *)iface;
TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This, lpEnumAddressCallback, lpAddress,
dwAddressSize, lpContext );
return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
}
extern HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress,
DWORD dwAddressSize, LPVOID lpContext )
{
DWORD dwTotalSizeEnumerated = 0;
/* FIXME: First chunk is always the total size chunk - Should we report it? */
while ( dwTotalSizeEnumerated < dwAddressSize )
{
const DPADDRESS* lpElements = (const DPADDRESS*)lpAddress;
DWORD dwSizeThisEnumeration;
/* Invoke the enum method. If false is returned, stop enumeration */
if ( !lpEnumAddressCallback( &lpElements->guidDataType,
lpElements->dwDataSize,
(BYTE*)lpElements + sizeof( DPADDRESS ),
lpContext ) )
{
break;
}
dwSizeThisEnumeration = sizeof( DPADDRESS ) + lpElements->dwDataSize;
lpAddress = (const BYTE*) lpAddress + dwSizeThisEnumeration;
dwTotalSizeEnumerated += dwSizeThisEnumeration;
}
return DP_OK;
}
/********************************************************************
*
* Enumerates all the address types that a given service provider needs to
* build the DirectPlay Address.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
( LPDIRECTPLAYLOBBYA iface,
LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
REFGUID guidSP,
LPVOID lpContext,
DWORD dwFlags )
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
HKEY hkResult;
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
DWORD dwIndex, sizeOfSubKeyName=50;
char subKeyName[51];
FILETIME filetime;
TRACE(" (%p)->(%p,%p,%p,0x%08lx)\n", This, lpEnumAddressTypeCallback, guidSP, lpContext, dwFlags );
if( dwFlags != 0 )
{
return DPERR_INVALIDPARAMS;
}
if( !lpEnumAddressTypeCallback || !*lpEnumAddressTypeCallback )
{
return DPERR_INVALIDPARAMS;
}
if( guidSP == NULL )
{
return DPERR_INVALIDOBJECT;
}
/* Need to loop over the service providers in the registry */
if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
{
/* Hmmm. Does this mean that there are no service providers? */
ERR(": no service providers?\n");
return DP_OK;
}
/* Traverse all the service providers we have available */
for( dwIndex=0;
RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
++dwIndex, sizeOfSubKeyName=50 )
{
HKEY hkServiceProvider, hkServiceProviderAt;
GUID serviceProviderGUID;
DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
char atSubKey[51];
char returnBuffer[51];
WCHAR buff[51];
DWORD dwAtIndex;
LPCSTR atKey = "Address Types";
LPCSTR guidDataSubKey = "Guid";
FILETIME filetime;
TRACE(" this time through: %s\n", subKeyName );
/* Get a handle for this particular service provider */
if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
&hkServiceProvider ) != ERROR_SUCCESS )
{
ERR(": what the heck is going on?\n" );
continue;
}
if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
NULL, &returnTypeGUID, (LPBYTE)returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR(": missing GUID registry data members\n" );
continue;
}
/* FIXME: Check return types to ensure we're interpreting data right */
MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, sizeof(buff)/sizeof(WCHAR) );
CLSIDFromString( buff, &serviceProviderGUID );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
/* Determine if this is the Service Provider that the user asked for */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -