📄 dplobby.c
字号:
if( !IsEqualGUID( &serviceProviderGUID, guidSP ) )
{
continue;
}
/* Get a handle for this particular service provider */
if( RegOpenKeyExA( hkServiceProvider, atKey, 0, KEY_READ,
&hkServiceProviderAt ) != ERROR_SUCCESS )
{
TRACE(": No Address Types registry data sub key/members\n" );
break;
}
/* Traverse all the address type we have available */
for( dwAtIndex=0;
RegEnumKeyExA( hkServiceProviderAt, dwAtIndex, atSubKey, &sizeOfSubKeyName,
NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
++dwAtIndex, sizeOfSubKeyName=50 )
{
TRACE( "Found Address Type GUID %s\n", atSubKey );
/* FIXME: Check return types to ensure we're interpreting data right */
MultiByteToWideChar( CP_ACP, 0, atSubKey, -1, buff, sizeof(buff)/sizeof(WCHAR) );
CLSIDFromString( buff, &serviceProviderGUID );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
/* The enumeration will return FALSE if we are not to continue */
if( !lpEnumAddressTypeCallback( &serviceProviderGUID, lpContext, 0 ) )
{
WARN("lpEnumCallback returning FALSE\n" );
break; /* FIXME: This most likely has to break from the procedure...*/
}
}
/* We only enumerate address types for 1 GUID. We've found it, so quit looking */
break;
}
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
( LPDIRECTPLAYLOBBY iface,
LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
REFGUID guidSP,
LPVOID lpContext,
DWORD dwFlags )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Enumerates what applications are registered with DirectPlay by
* invoking the callback function with lpContext.
*
*/
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
( LPDIRECTPLAYLOBBY iface,
LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback,
LPVOID lpContext,
DWORD dwFlags )
{
IDirectPlayLobbyWImpl *This = (IDirectPlayLobbyWImpl *)iface;
FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
( LPDIRECTPLAYLOBBYA iface,
LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback,
LPVOID lpContext,
DWORD dwFlags )
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
HKEY hkResult;
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
LPCSTR guidDataSubKey = "Guid";
DWORD dwIndex, sizeOfSubKeyName=50;
char subKeyName[51];
FILETIME filetime;
TRACE("(%p)->(%p,%p,0x%08lx)\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
if( dwFlags != 0 )
{
return DPERR_INVALIDPARAMS;
}
if( !lpEnumLocalAppCallback || !*lpEnumLocalAppCallback )
{
return DPERR_INVALIDPARAMS;
}
/* 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 registered applications */
for( dwIndex=0;
RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
++dwIndex, sizeOfSubKeyName=50 )
{
HKEY hkServiceProvider;
GUID serviceProviderGUID;
DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
char returnBuffer[51];
WCHAR buff[51];
DPLAPPINFO dplAppInfo;
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? */
dplAppInfo.dwSize = sizeof( dplAppInfo );
dplAppInfo.guidApplication = serviceProviderGUID;
dplAppInfo.u.lpszAppNameA = subKeyName;
EnterCriticalSection( &This->unk->DPL_lock );
memcpy( &This->dpl->hkCallbackKeyHack, &hkServiceProvider, sizeof( hkServiceProvider ) );
if( !lpEnumLocalAppCallback( &dplAppInfo, lpContext, dwFlags ) )
{
LeaveCriticalSection( &This->unk->DPL_lock );
break;
}
LeaveCriticalSection( &This->unk->DPL_lock );
}
return DP_OK;
}
/********************************************************************
*
* Retrieves the DPLCONNECTION structure that contains all the information
* needed to start and connect an application. This was generated using
* either the RunApplication or SetConnectionSettings methods.
*
* NOTES: If lpData is NULL then just return lpdwDataSize. This allows
* the data structure to be allocated by our caller which can then
* call this procedure/method again with a valid data pointer.
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
( LPDIRECTPLAYLOBBYA iface,
DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
HRESULT hr;
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
EnterCriticalSection( &This->unk->DPL_lock );
hr = DPLAYX_GetConnectionSettingsA( dwAppID,
lpData,
lpdwDataSize
);
LeaveCriticalSection( &This->unk->DPL_lock );
return hr;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
( LPDIRECTPLAYLOBBY iface,
DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
IDirectPlayLobbyWImpl *This = (IDirectPlayLobbyWImpl *)iface;
HRESULT hr;
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
EnterCriticalSection( &This->unk->DPL_lock );
hr = DPLAYX_GetConnectionSettingsW( dwAppID,
lpData,
lpdwDataSize
);
LeaveCriticalSection( &This->unk->DPL_lock );
return hr;
}
/********************************************************************
*
* Retrieves the message sent between a lobby client and a DirectPlay
* application. All messages are queued until received.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
DWORD dwAppID,
LPDWORD lpdwMessageFlags,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
IDirectPlayLobbyAImpl *This = (IDirectPlayLobbyAImpl *)iface;
FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
lpdwDataSize );
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
DWORD dwAppID,
LPDWORD lpdwMessageFlags,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
IDirectPlayLobbyWImpl *This = (IDirectPlayLobbyWImpl *)iface;
FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
lpdwDataSize );
return DPERR_OUTOFMEMORY;
}
typedef struct tagRunApplicationEnumStruct
{
IDirectPlayLobbyAImpl* This;
GUID appGUID;
LPSTR lpszPath;
LPSTR lpszFileName;
LPSTR lpszCommandLine;
LPSTR lpszCurrentDirectory;
} RunApplicationEnumStruct, *lpRunApplicationEnumStruct;
/* To be called by RunApplication to find how to invoke the function */
static BOOL CALLBACK RunApplicationA_EnumLocalApplications
( LPCDPLAPPINFO lpAppInfo,
LPVOID lpContext,
DWORD dwFlags )
{
lpRunApplicationEnumStruct lpData = (lpRunApplicationEnumStruct)lpContext;
if( IsEqualGUID( &lpAppInfo->guidApplication, &lpData->appGUID ) )
{
char returnBuffer[200];
DWORD returnType, sizeOfReturnBuffer;
LPCSTR clSubKey = "CommandLine";
LPCSTR cdSubKey = "CurrentDirectory";
LPCSTR fileSubKey = "File";
LPCSTR pathSubKey = "Path";
/* FIXME: Lazy man hack - dplay struct has the present reg key saved */
sizeOfReturnBuffer = 200;
/* Get all the appropriate data from the registry */
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, clSubKey,
NULL, &returnType, (LPBYTE)returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing CommandLine registry data member\n" );
}
else
{
if ((lpData->lpszCommandLine = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
strcpy( lpData->lpszCommandLine, returnBuffer );
}
sizeOfReturnBuffer = 200;
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, cdSubKey,
NULL, &returnType, (LPBYTE)returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing CurrentDirectory registry data member\n" );
}
else
{
if ((lpData->lpszCurrentDirectory = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
strcpy( lpData->lpszCurrentDirectory, returnBuffer );
}
sizeOfReturnBuffer = 200;
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, fileSubKey,
NULL, &returnType, (LPBYTE)returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing File registry data member\n" );
}
else
{
if ((lpData->lpszFileName = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
strcpy( lpData->lpszFileName, returnBuffer );
}
sizeOfReturnBuffer = 200;
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, pathSubKey,
NULL, &returnType, (LPBYTE)returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing Path registry data member\n" );
}
else
{
if ((lpData->lpszPath = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 )))
strcpy( lpData->lpszPath, returnBuffer );
}
return FALSE; /* No need to keep going as we found what we wanted */
}
return TRUE; /* Keep enumerating, haven't found the application yet */
}
BOOL DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId, HANDLE hDestProcess,
LPHANDLE lphStart, LPHANDLE lphDeath,
LPHANDLE lphRead )
{
/* These are the handles for the created process */
HANDLE hAppStart = 0, hAppDeath = 0, hAppRead = 0;
SECURITY_ATTRIBUTES s_attrib;
s_attrib.nLength = sizeof( s_attrib );
s_attrib.lpSecurityDescriptor = NULL;
s_attrib.bInheritHandle = TRUE;
*lphStart = CreateEventW( &s_attrib, TRUE, FALSE, NULL );
*lphDeath = CreateEventW( &s_attrib, TRUE, FALSE, NULL );
*lphRead = CreateEventW( &s_attrib, TRUE, FALSE, NULL );
if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart,
hDestProcess, &hAppStart,
0, FALSE, DUPLICATE_SAME_ACCESS ) ) ||
( !DuplicateHandle( GetCurrentProcess(), *lphDeath,
hDestProcess, &hAppDeath,
0, FALSE, DUPLICATE_SAME_ACCESS ) ) ||
( !DuplicateHandle( GetCurrentProcess(), *lphRead,
hDestProcess, &hAppRead,
0, FALSE, DUPLICATE_SAME_ACCESS ) )
)
{
if (*lphStart) { CloseHandle(*lphStart); *lphStart = 0; }
if (*lphDeath) { CloseHandle(*lphDeath); *lphDeath = 0; }
if (*lphRead) { CloseHandle(*lphRead); *lphRead = 0; }
/* FIXME: Handle leak... */
ERR( "Unable to dup handles\n" );
return FALSE;
}
if( !DPLAYX_SetLobbyHandles( dwDestProcessId,
hAppStart, hAppDeath, hAppRead ) )
{
/* FIXME: Handle leak... */
return FALSE;
}
return TRUE;
}
/********************************************************************
*
* Starts an application and passes to it all the information to
* connect to a session.
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -