Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
7.8 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dpvxdplay.cpp
  6. * Content: Useful dplay utility functions lib for sample apps
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 10/07/99 rodtoll Created It
  12. * 10/27/99 pnewson Added support for application flags
  13. * 11/02/99 rodtoll Bug #116677 - Can't use lobby clients that don't hang around
  14. * 12/16/99 rodtoll Bug #122629 - Player was being created as server player exposed
  15. * by new host migration
  16. * 03/03/2000 rodtoll Updated to handle alternative gamevoice build.
  17. * 08/31/2000 rodtoll Whistler Bug #171844, 171842
  18. *
  19. ***************************************************************************/
  20. #include "dpvxlibpch.h"
  21. // Start a session with the specified settings.
  22. HRESULT DPVDX_DP_StartSession(
  23. // Input
  24. LPDIRECTPLAY4A lpDirectPlay,
  25. GUID guidApplicationID,
  26. DWORD dwFlags,
  27. LPTSTR lpszPlayerName,
  28. LPTSTR lpszSessionName,
  29. DWORD dwMaxPlayers,
  30. // Output
  31. LPDPID lpdpidServerID,
  32. LPHANDLE lpReceiveEvent,
  33. LPGUID lpguidInstanceGUID
  34. )
  35. {
  36. HRESULT hr;
  37. // Create and intialize the server
  38. DPSESSIONDESC2 dpSessionDesc;
  39. memset( &dpSessionDesc, 0, sizeof( DPSESSIONDESC2 ) );
  40. dpSessionDesc.dwSize = sizeof( DPSESSIONDESC2 );
  41. dpSessionDesc.dwFlags = DPSESSION_DIRECTPLAYPROTOCOL;
  42. dpSessionDesc.dwFlags |= dwFlags;
  43. dpSessionDesc.guidApplication = guidApplicationID;
  44. dpSessionDesc.dwMaxPlayers = dwMaxPlayers;
  45. dpSessionDesc.lpszSessionNameA = lpszSessionName;
  46. dpSessionDesc.lpszPasswordA = NULL;
  47. DPNAME tmpName;
  48. tmpName.dwSize = sizeof(DPNAME);
  49. tmpName.lpszShortNameA = lpszPlayerName;
  50. tmpName.lpszLongNameA = lpszPlayerName;
  51. hr = lpDirectPlay->Open( &dpSessionDesc, DPOPEN_CREATE );
  52. if( FAILED( hr ) )
  53. {
  54. goto STARTSESSION_ERROR;
  55. }
  56. *lpReceiveEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  57. hr = lpDirectPlay->CreatePlayer( lpdpidServerID, &tmpName, *lpReceiveEvent, NULL, 0, (dwFlags & DPSESSION_CLIENTSERVER) ? DPPLAYER_SERVERPLAYER : 0 );
  58. if( FAILED( hr ) )
  59. {
  60. goto STARTSESSION_ERROR;
  61. }
  62. return DV_OK;
  63. STARTSESSION_ERROR:
  64. return hr;
  65. }
  66. HRESULT DPVDX_DP_Init( LPDIRECTPLAY4A lpDirectPlay, GUID guidServiceProvider, LPSTR lpstrAddress )
  67. {
  68. if( lpDirectPlay == NULL )
  69. return E_POINTER;
  70. HRESULT hr = DV_OK;
  71. DPCOMPOUNDADDRESSELEMENT elements[2];
  72. BYTE *buffer = NULL;
  73. DWORD dwSize = 0;
  74. LPDIRECTPLAYLOBBY2 directPlayLobby2 = NULL;
  75. DWORD dwNumElements = 1;
  76. hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby2, (void **) &directPlayLobby2 );
  77. if( FAILED( hr ) )
  78. goto DPINIT_CLEANUP;
  79. elements[0].guidDataType = DPAID_ServiceProvider;
  80. elements[0].dwDataSize = sizeof( GUID );
  81. elements[0].lpData = (LPVOID) &guidServiceProvider;
  82. if( lpstrAddress != NULL )
  83. {
  84. dwNumElements = 2;
  85. elements[1].guidDataType = DPAID_INet;
  86. elements[1].dwDataSize = strlen( lpstrAddress );
  87. elements[1].lpData = lpstrAddress;
  88. }
  89. // Determine size of the buffer we need
  90. hr = directPlayLobby2->CreateCompoundAddress( elements, dwNumElements, NULL, &dwSize );
  91. if( hr != DPERR_BUFFERTOOSMALL && FAILED( hr ) )
  92. goto DPINIT_CLEANUP;
  93. buffer = new BYTE[dwSize];
  94. if( buffer == NULL )
  95. {
  96. hr = DVERR_OUTOFMEMORY;
  97. goto DPINIT_CLEANUP;
  98. }
  99. // Actually allocate the connection information
  100. hr = directPlayLobby2->CreateCompoundAddress( elements, dwNumElements, buffer, &dwSize );
  101. if( FAILED( hr ) )
  102. {
  103. goto DPINIT_CLEANUP;
  104. }
  105. hr = lpDirectPlay->InitializeConnection( buffer, 0 );
  106. if( FAILED( hr ) )
  107. {
  108. goto DPINIT_CLEANUP;
  109. }
  110. hr = DV_OK;
  111. DPINIT_CLEANUP:
  112. if( buffer != NULL )
  113. delete [] buffer;
  114. if( directPlayLobby2 != NULL )
  115. directPlayLobby2->Release();
  116. return hr;
  117. }
  118. BOOL FAR PASCAL DPVDX_EnumHandler(
  119. LPCDPSESSIONDESC2 lpThisSD,
  120. LPDWORD lpdwTimeOut,
  121. DWORD dwFlags,
  122. LPVOID lpContext
  123. )
  124. {
  125. LPGUID tmpGUID = (LPGUID) lpContext;
  126. if( lpThisSD != NULL && tmpGUID != NULL )
  127. {
  128. *tmpGUID = lpThisSD->guidInstance;
  129. return FALSE;
  130. }
  131. return FALSE;
  132. }
  133. HRESULT DPVDX_DP_FindSessionGUID(
  134. LPDIRECTPLAY4A lpDirectPlay,
  135. // Input
  136. GUID guidApplicationID,
  137. DWORD dwTimeout,
  138. // Output
  139. LPGUID lpguidInstance )
  140. {
  141. HRESULT hr = DV_OK;
  142. DPSESSIONDESC2 dpSessionDesc;
  143. DWORD dwTime;
  144. if( lpguidInstance == NULL )
  145. return E_POINTER;
  146. memset( &dpSessionDesc, 0, sizeof( DPSESSIONDESC2 ) );
  147. dpSessionDesc.dwSize = sizeof( DPSESSIONDESC2 );
  148. dpSessionDesc.guidApplication = guidApplicationID;
  149. dpSessionDesc.lpszPassword = NULL;
  150. dwTime = GetTickCount();
  151. while( (GetTickCount() - dwTime) < dwTimeout )
  152. {
  153. lpDirectPlay->EnumSessions( &dpSessionDesc, 0, DPVDX_EnumHandler, &dpSessionDesc.guidInstance, DPENUMSESSIONS_ASYNC );
  154. if( dpSessionDesc.guidInstance != GUID_NULL )
  155. break;
  156. Sleep( 10 );
  157. }
  158. // lpDirectPlay->EnumSessions( &dpSessionDesc, 0, DPVDX_EnumHandler, NULL, DPENUMSESSIONS_STOPASYNC );
  159. if( dpSessionDesc.guidInstance == GUID_NULL )
  160. {
  161. return DPERR_NOSESSIONS;
  162. }
  163. *lpguidInstance = dpSessionDesc.guidInstance;
  164. return DV_OK;
  165. }
  166. HRESULT DPVDX_DP_ConnectToSession(
  167. // Input
  168. LPDIRECTPLAY4A lpDirectPlay,
  169. GUID guidApplication,
  170. GUID guidInstance,
  171. LPTSTR lpszPlayerName,
  172. // Output
  173. LPDPID lpdpidClientID,
  174. LPHANDLE lpReceiveEvent
  175. )
  176. {
  177. DPSESSIONDESC2 dpSessionDesc;
  178. HRESULT hr;
  179. DPNAME dpnameTmp;
  180. memset( &dpSessionDesc, 0, sizeof( DPSESSIONDESC2 ) );
  181. dpSessionDesc.dwSize = sizeof( DPSESSIONDESC2 );
  182. dpSessionDesc.guidApplication = guidApplication;
  183. dpSessionDesc.guidInstance = guidInstance;
  184. dpSessionDesc.lpszPassword = NULL;
  185. hr = lpDirectPlay->Open( &dpSessionDesc, DPOPEN_JOIN );
  186. if( FAILED( hr ) )
  187. return hr;
  188. dpnameTmp.dwSize = sizeof(DPNAME);
  189. dpnameTmp.lpszShortNameA = lpszPlayerName;
  190. dpnameTmp.lpszLongNameA = lpszPlayerName;
  191. *lpReceiveEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  192. hr = lpDirectPlay->CreatePlayer( lpdpidClientID, NULL, *lpReceiveEvent, NULL, 0, 0 );
  193. return hr;
  194. }
  195. HRESULT DPVDX_DP_RegisterApplication(
  196. LPSTR lpstrAppName,
  197. GUID guidApplication,
  198. LPTSTR lpstrExeName,
  199. LPTSTR lpstrCommandLine,
  200. LPTSTR lpstrDescription,
  201. DWORD dwFlags
  202. )
  203. {
  204. HRESULT hr;
  205. LPDIRECTPLAYLOBBY3A lpdpLobby;
  206. DPAPPLICATIONDESC dpappDesc;
  207. if( !lpstrAppName || !lpstrExeName || !lpstrCommandLine || !lpstrDescription )
  208. {
  209. return DVERR_GENERIC;
  210. }
  211. char szEXEPathname[_MAX_PATH];
  212. szEXEPathname[0] = 0;
  213. if( !GetModuleFileName(NULL, szEXEPathname, _MAX_PATH) )
  214. {
  215. return DVERR_GENERIC;
  216. }
  217. hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby3A, (void **) &lpdpLobby );
  218. if( FAILED( hr ) )
  219. {
  220. return hr;
  221. }
  222. szEXEPathname[strlen(szEXEPathname)-strlen(lpstrExeName)] = 0;
  223. dpappDesc.dwSize = sizeof(DPAPPLICATIONDESC);
  224. dpappDesc.dwFlags = dwFlags;
  225. dpappDesc.lpszApplicationNameA = lpstrAppName;
  226. dpappDesc.lpszFilenameA = lpstrExeName;
  227. dpappDesc.lpszCommandLineA = lpstrCommandLine;
  228. dpappDesc.lpszPathA = szEXEPathname;
  229. dpappDesc.lpszCurrentDirectoryA = szEXEPathname;
  230. dpappDesc.lpszDescriptionA = lpstrDescription;
  231. wchar_t lpwstrTmp[_MAX_PATH];
  232. if( DPVDX_AnsiToWide( lpwstrTmp, lpstrDescription, _MAX_PATH ) != 0 )
  233. {
  234. dpappDesc.lpszDescriptionW = lpwstrTmp;
  235. }
  236. else
  237. {
  238. dpappDesc.lpszDescriptionW = NULL;
  239. }
  240. dpappDesc.guidApplication = guidApplication;
  241. hr = lpdpLobby->RegisterApplication( 0, &dpappDesc );
  242. lpdpLobby->Release();
  243. return hr;
  244. }
  245. HRESULT DPVDX_DP_UnRegisterApplication( GUID guidApplication )
  246. {
  247. HRESULT hr;
  248. LPDIRECTPLAYLOBBY3A lpdpLobby;
  249. hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby3A, (void **) &lpdpLobby );
  250. if( FAILED( hr ) )
  251. {
  252. return hr;
  253. }
  254. hr = lpdpLobby->UnregisterApplication( 0, guidApplication );
  255. lpdpLobby->Release();
  256. return hr;
  257. }