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.

926 lines
30 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DPLConset.cpp
  6. * Content: DirectPlay Lobby Connection Settings Utility Functions
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 06/13/00 rmt Created
  12. * 07/07/00 rmt Bug #38755 - No way to specify player name in connection settings
  13. * 07/08/2000 rmt Bug #38725 - Need to provide method to detect if app was lobby launched
  14. * rmt Bug #38757 - Callback messages for connections may return AFTER WaitForConnection returns
  15. * rmt Bug #38755 - No way to specify player name in Connection Settings
  16. * rmt Bug #38758 - DPLOBBY8.H has incorrect comments
  17. * rmt Bug #38783 - pvUserApplicationContext is only partially implemented
  18. * rmt Added DPLHANDLE_ALLCONNECTIONS and dwFlags (reserved field to couple of funcs).
  19. * 07/12/2000 rmt Removed improper assert
  20. * 02/06/2001 rodtoll WINBUG #293871: DPLOBBY8: [IA64] Lobby launching a 64-bit
  21. * app from 64-bit lobby launcher crashes with unaligned memory error.
  22. *@@END_MSINTERNAL
  23. *
  24. ***************************************************************************/
  25. #include "dnlobbyi.h"
  26. #undef DPF_MODNAME
  27. #define DPF_MODNAME "CConnectionSettings::CConnectionSettings"
  28. CConnectionSettings::CConnectionSettings(): m_dwSignature(DPLSIGNATURE_LOBBYCONSET), m_fManaged(FALSE), m_pdplConnectionSettings(NULL), m_fCritSecInited(FALSE)
  29. {
  30. }
  31. CConnectionSettings::~CConnectionSettings()
  32. {
  33. if( !m_fManaged && m_pdplConnectionSettings )
  34. {
  35. FreeConnectionSettings( m_pdplConnectionSettings );
  36. m_pdplConnectionSettings = NULL;
  37. }
  38. if (m_fCritSecInited)
  39. {
  40. DNDeleteCriticalSection( &m_csLock );
  41. }
  42. m_dwSignature = DPLSIGNATURE_LOBBYCONSET_FREE;
  43. }
  44. #undef DPF_MODNAME
  45. #define DPF_MODNAME "CConnectionSettings::FreeConnectionSettings"
  46. // CConnectionSettings::FreeConnectionSettings
  47. //
  48. // This function frees the memory associated with the specified connection
  49. void CConnectionSettings::FreeConnectionSettings( DPL_CONNECTION_SETTINGS *pConnectionSettings )
  50. {
  51. if( pConnectionSettings )
  52. {
  53. if( pConnectionSettings->pwszPlayerName )
  54. {
  55. delete [] pConnectionSettings->pwszPlayerName;
  56. pConnectionSettings->pwszPlayerName = NULL;
  57. }
  58. if( pConnectionSettings->dpnAppDesc.pwszSessionName )
  59. {
  60. delete [] pConnectionSettings->dpnAppDesc.pwszSessionName;
  61. pConnectionSettings->dpnAppDesc.pwszSessionName = NULL;
  62. }
  63. if( pConnectionSettings->dpnAppDesc.pwszPassword )
  64. {
  65. delete [] pConnectionSettings->dpnAppDesc.pwszPassword;
  66. pConnectionSettings->dpnAppDesc.pwszPassword = NULL;
  67. }
  68. if( pConnectionSettings->dpnAppDesc.pvReservedData )
  69. {
  70. delete [] pConnectionSettings->dpnAppDesc.pvReservedData;
  71. pConnectionSettings->dpnAppDesc.pvReservedData = NULL;
  72. }
  73. if( pConnectionSettings->dpnAppDesc.pvApplicationReservedData )
  74. {
  75. delete [] pConnectionSettings->dpnAppDesc.pvApplicationReservedData;
  76. pConnectionSettings->dpnAppDesc.pvApplicationReservedData = NULL;
  77. }
  78. if( pConnectionSettings->pdp8HostAddress )
  79. {
  80. pConnectionSettings->pdp8HostAddress->lpVtbl->Release( pConnectionSettings->pdp8HostAddress );
  81. pConnectionSettings->pdp8HostAddress = NULL;
  82. }
  83. if( pConnectionSettings->ppdp8DeviceAddresses )
  84. {
  85. for( DWORD dwIndex = 0; dwIndex < pConnectionSettings->cNumDeviceAddresses; dwIndex++ )
  86. {
  87. pConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->Release( pConnectionSettings->ppdp8DeviceAddresses[dwIndex] );
  88. }
  89. delete [] pConnectionSettings->ppdp8DeviceAddresses;
  90. pConnectionSettings->ppdp8DeviceAddresses = NULL;
  91. }
  92. delete pConnectionSettings;
  93. }
  94. }
  95. #undef DPF_MODNAME
  96. #define DPF_MODNAME "CConnectionSettings::Initialize"
  97. // Initialize (DPL_CONNECTION_SETTINGS version)
  98. //
  99. // This function tells this class to take the specified connection settings and
  100. // work with it.
  101. //
  102. HRESULT CConnectionSettings::Initialize( DPL_CONNECTION_SETTINGS * pdplSettings )
  103. {
  104. if (!DNInitializeCriticalSection( &m_csLock ) )
  105. {
  106. DPFX(DPFPREP, 0, "Failed to create critical section");
  107. return DPNERR_OUTOFMEMORY;
  108. }
  109. m_fCritSecInited = TRUE;
  110. m_pdplConnectionSettings = pdplSettings;
  111. m_fManaged = FALSE;
  112. return DPN_OK;
  113. }
  114. #undef DPF_MODNAME
  115. #define DPF_MODNAME "CConnectionSettings::Initialize"
  116. // Initialize (Wire Version)
  117. //
  118. // THis function initializes this object to contain a connection settings structure
  119. // that mirrors the values of the wire message.
  120. HRESULT CConnectionSettings::Initialize( UNALIGNED DPL_INTERNAL_CONNECTION_SETTINGS *pdplSettingsMsg, UNALIGNED BYTE * pbBufferStart )
  121. {
  122. DNASSERT( pdplSettingsMsg );
  123. HRESULT hr = DPN_OK;
  124. DPL_CONNECTION_SETTINGS *pdplConnectionSettings = NULL;
  125. UNALIGNED BYTE *pBasePointer = pbBufferStart;
  126. PDIRECTPLAY8ADDRESS pdp8Address = NULL;
  127. WCHAR *wszTmpAlignedBuffer = NULL;
  128. DWORD dwTmpOffset = 0;
  129. DWORD dwTmpLength = 0;
  130. UNALIGNED DWORD *pdwOffsets = NULL;
  131. UNALIGNED DWORD *pdwLengths = NULL;
  132. if (!DNInitializeCriticalSection( &m_csLock ) )
  133. {
  134. DPFX(DPFPREP, 0, "Failed to create critical section");
  135. return DPNERR_OUTOFMEMORY;
  136. }
  137. m_fCritSecInited = TRUE;
  138. pdplConnectionSettings = new DPL_CONNECTION_SETTINGS;
  139. if( !pdplConnectionSettings )
  140. {
  141. hr = DPNERR_OUTOFMEMORY;
  142. goto INITIALIZE_FAILED;
  143. }
  144. // Zero out the memory
  145. ZeroMemory( pdplConnectionSettings, sizeof( DPL_CONNECTION_SETTINGS ) );
  146. pdplConnectionSettings->dwSize = sizeof( DPL_CONNECTION_SETTINGS );
  147. pdplConnectionSettings->dwFlags = pdplSettingsMsg->dwFlags;
  148. //
  149. // PLAYER NAME COPY
  150. //
  151. if( pdplSettingsMsg->dwPlayerNameLength )
  152. {
  153. pdplConnectionSettings->pwszPlayerName = new WCHAR[pdplSettingsMsg->dwPlayerNameLength >> 1];
  154. if( !pdplConnectionSettings->pwszPlayerName )
  155. {
  156. hr = DPNERR_OUTOFMEMORY;
  157. goto INITIALIZE_FAILED;
  158. }
  159. memcpy( pdplConnectionSettings->pwszPlayerName, pBasePointer + pdplSettingsMsg->dwPlayerNameOffset,
  160. pdplSettingsMsg->dwPlayerNameLength );
  161. }
  162. //
  163. // HOST ADDRESS COPY
  164. //
  165. if( pdplSettingsMsg->dwHostAddressLength )
  166. {
  167. // We need to create a buffer for string that we know is aligned. - Ick -
  168. wszTmpAlignedBuffer = new WCHAR[pdplSettingsMsg->dwHostAddressLength >> 1];
  169. if( !wszTmpAlignedBuffer )
  170. {
  171. hr = DPNERR_OUTOFMEMORY;
  172. goto INITIALIZE_FAILED;
  173. }
  174. // Copy the potentially unaligned data to the aligned data string.
  175. memcpy( wszTmpAlignedBuffer, pBasePointer + pdplSettingsMsg->dwHostAddressOffset,pdplSettingsMsg->dwHostAddressLength );
  176. hr = COM_CoCreateInstance( CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Address, (void **) &pdp8Address );
  177. if( FAILED( hr ) )
  178. {
  179. DPFX(DPFPREP, 0, "Error creating address hr=0x%x", hr );
  180. goto INITIALIZE_FAILED;
  181. }
  182. // Convert the host address (if there is one)
  183. hr = pdp8Address->lpVtbl->BuildFromURLW( pdp8Address, wszTmpAlignedBuffer );
  184. if( FAILED( hr ) )
  185. {
  186. DPFX(DPFPREP, 0, "Error building URL from address hr=0x%x", hr );
  187. goto INITIALIZE_FAILED;
  188. }
  189. pdplConnectionSettings->pdp8HostAddress = pdp8Address;
  190. pdp8Address = NULL;
  191. if( wszTmpAlignedBuffer )
  192. {
  193. delete [] wszTmpAlignedBuffer;
  194. wszTmpAlignedBuffer = NULL;
  195. }
  196. }
  197. if( pdplSettingsMsg->dwNumDeviceAddresses )
  198. {
  199. pdplConnectionSettings->cNumDeviceAddresses = pdplSettingsMsg->dwNumDeviceAddresses;
  200. //
  201. // DEVICE ADDRESS COPY
  202. //
  203. pdplConnectionSettings->ppdp8DeviceAddresses = new PDIRECTPLAY8ADDRESS[pdplSettingsMsg->dwNumDeviceAddresses];
  204. if( !pdplConnectionSettings->ppdp8DeviceAddresses )
  205. {
  206. hr = DPNERR_OUTOFMEMORY;
  207. goto INITIALIZE_FAILED;
  208. }
  209. // Give us an unaligned dword pointer to the device addresses offset
  210. pdwOffsets = (UNALIGNED DWORD *) (pBasePointer + pdplSettingsMsg->dwDeviceAddressOffset);
  211. pdwLengths = (UNALIGNED DWORD *) (pBasePointer + pdplSettingsMsg->dwDeviceAddressLengthOffset);
  212. for( DWORD dwIndex = 0; dwIndex < pdplSettingsMsg->dwNumDeviceAddresses; dwIndex++ )
  213. {
  214. dwTmpOffset = pdwOffsets[dwIndex];
  215. dwTmpLength = pdwLengths[dwIndex];
  216. // We need to create a buffer for string that we know is aligned. - Ick -
  217. wszTmpAlignedBuffer = new WCHAR[dwTmpLength >> 1];
  218. if( !wszTmpAlignedBuffer )
  219. {
  220. hr = DPNERR_OUTOFMEMORY;
  221. goto INITIALIZE_FAILED;
  222. }
  223. memcpy( wszTmpAlignedBuffer, pBasePointer + dwTmpOffset, dwTmpLength );
  224. hr = COM_CoCreateInstance( CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Address, (void **) &pdp8Address );
  225. if( FAILED( hr ) )
  226. {
  227. DPFX(DPFPREP, 0, "Error creating address hr=0x%x", hr );
  228. return hr;
  229. }
  230. // Convert the host address (if there is one)
  231. hr = pdp8Address->lpVtbl->BuildFromURLW( pdp8Address, wszTmpAlignedBuffer );
  232. if( FAILED( hr ) )
  233. {
  234. DPFX(DPFPREP, 0, "Error building URL from address hr=0x%x", hr );
  235. DNASSERT( FALSE );
  236. return hr;
  237. }
  238. pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex] = pdp8Address;
  239. pdp8Address = NULL;
  240. if( wszTmpAlignedBuffer )
  241. {
  242. delete [] wszTmpAlignedBuffer;
  243. wszTmpAlignedBuffer = NULL;
  244. }
  245. }
  246. }
  247. else
  248. {
  249. pdplConnectionSettings->ppdp8DeviceAddresses = NULL;
  250. }
  251. //
  252. // APPLICATION DESCRIPTION COPY
  253. //
  254. pdplConnectionSettings->dpnAppDesc.dwSize = sizeof( DPN_APPLICATION_DESC );
  255. pdplConnectionSettings->dpnAppDesc.dwFlags = pdplSettingsMsg->dpnApplicationDesc.dwFlags;
  256. pdplConnectionSettings->dpnAppDesc.guidInstance = pdplSettingsMsg->dpnApplicationDesc.guidInstance;
  257. pdplConnectionSettings->dpnAppDesc.guidApplication = pdplSettingsMsg->dpnApplicationDesc.guidApplication;
  258. pdplConnectionSettings->dpnAppDesc.dwMaxPlayers = pdplSettingsMsg->dpnApplicationDesc.dwMaxPlayers;
  259. pdplConnectionSettings->dpnAppDesc.dwCurrentPlayers = pdplSettingsMsg->dpnApplicationDesc.dwCurrentPlayers;
  260. if( pdplSettingsMsg->dpnApplicationDesc.dwSessionNameSize )
  261. {
  262. pdplConnectionSettings->dpnAppDesc.pwszSessionName = new WCHAR[pdplSettingsMsg->dpnApplicationDesc.dwSessionNameSize >> 1];
  263. if( !pdplConnectionSettings->dpnAppDesc.pwszSessionName )
  264. {
  265. hr = DPNERR_OUTOFMEMORY;
  266. goto INITIALIZE_FAILED;
  267. }
  268. memcpy( pdplConnectionSettings->dpnAppDesc.pwszSessionName,
  269. pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwSessionNameOffset,
  270. pdplSettingsMsg->dpnApplicationDesc.dwSessionNameSize );
  271. }
  272. if( pdplSettingsMsg->dpnApplicationDesc.dwPasswordSize )
  273. {
  274. pdplConnectionSettings->dpnAppDesc.pwszPassword = new WCHAR[pdplSettingsMsg->dpnApplicationDesc.dwPasswordSize >> 1];
  275. if( !pdplConnectionSettings->dpnAppDesc.pwszPassword )
  276. {
  277. hr = DPNERR_OUTOFMEMORY;
  278. goto INITIALIZE_FAILED;
  279. }
  280. memcpy( pdplConnectionSettings->dpnAppDesc.pwszPassword,
  281. pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwPasswordOffset,
  282. pdplSettingsMsg->dpnApplicationDesc.dwPasswordSize );
  283. }
  284. if( pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize )
  285. {
  286. pdplConnectionSettings->dpnAppDesc.pvReservedData = new BYTE[pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize];
  287. if( !pdplConnectionSettings->dpnAppDesc.pvReservedData )
  288. {
  289. hr = DPNERR_OUTOFMEMORY;
  290. goto INITIALIZE_FAILED;
  291. }
  292. memcpy( pdplConnectionSettings->dpnAppDesc.pvReservedData,
  293. pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwReservedDataOffset,
  294. pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize );
  295. pdplConnectionSettings->dpnAppDesc.dwReservedDataSize = pdplSettingsMsg->dpnApplicationDesc.dwReservedDataSize;
  296. }
  297. if( pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize )
  298. {
  299. pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData = new BYTE[pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize];
  300. if( !pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData )
  301. {
  302. hr = DPNERR_OUTOFMEMORY;
  303. goto INITIALIZE_FAILED;
  304. }
  305. memcpy( pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData,
  306. pBasePointer + pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataOffset,
  307. pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize );
  308. pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize = pdplSettingsMsg->dpnApplicationDesc.dwApplicationReservedDataSize;
  309. }
  310. // Free the old structure if one exists.
  311. if( m_fManaged )
  312. {
  313. m_fManaged = FALSE;
  314. }
  315. else if( m_pdplConnectionSettings )
  316. {
  317. FreeConnectionSettings( m_pdplConnectionSettings );
  318. }
  319. m_pdplConnectionSettings = pdplConnectionSettings;
  320. if( wszTmpAlignedBuffer )
  321. delete [] wszTmpAlignedBuffer;
  322. return DPN_OK;
  323. INITIALIZE_FAILED:
  324. FreeConnectionSettings( pdplConnectionSettings );
  325. if( wszTmpAlignedBuffer )
  326. delete [] wszTmpAlignedBuffer;
  327. if( pdp8Address )
  328. pdp8Address->lpVtbl->Release( pdp8Address );
  329. return hr;
  330. }
  331. #undef DPF_MODNAME
  332. #define DPF_MODNAME "CConnectionSettings::InitializeAndCopy"
  333. // InitializeAndCopy
  334. //
  335. // This function initializes this class to contain a copy of the specified
  336. // connection settings structure.
  337. //
  338. HRESULT CConnectionSettings::InitializeAndCopy( const DPL_CONNECTION_SETTINGS * const pdplSettings )
  339. {
  340. DNASSERT( pdplSettings );
  341. HRESULT hr = DPN_OK;
  342. DPL_CONNECTION_SETTINGS *pdplConnectionSettings = NULL;
  343. if (!DNInitializeCriticalSection( &m_csLock ) )
  344. {
  345. DPFX(DPFPREP, 0, "Failed to create critical section");
  346. return DPNERR_OUTOFMEMORY;
  347. }
  348. m_fCritSecInited = TRUE;
  349. pdplConnectionSettings = new DPL_CONNECTION_SETTINGS;
  350. if( !pdplConnectionSettings )
  351. {
  352. hr = DPNERR_OUTOFMEMORY;
  353. goto INITIALIZE_FAILED;
  354. }
  355. // Copy over. This is a little dangerous as we copy pointer values. Pointers
  356. // should be set in our local structure to NULL so that proper cleanup can occur
  357. // on error. (Otherwise we'll free other structure's memory!!)
  358. memcpy( pdplConnectionSettings, pdplSettings, sizeof( DPL_CONNECTION_SETTINGS ) );
  359. // Reset pointers as mentioned above.
  360. pdplConnectionSettings->pdp8HostAddress = NULL;
  361. pdplConnectionSettings->ppdp8DeviceAddresses = NULL;
  362. pdplConnectionSettings->pwszPlayerName = NULL;
  363. pdplConnectionSettings->dpnAppDesc.pwszSessionName = NULL;
  364. pdplConnectionSettings->dpnAppDesc.pwszPassword = NULL;
  365. pdplConnectionSettings->dpnAppDesc.pvReservedData = NULL;
  366. pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData = NULL;
  367. if( pdplSettings->pdp8HostAddress )
  368. {
  369. hr = pdplSettings->pdp8HostAddress->lpVtbl->Duplicate( pdplSettings->pdp8HostAddress, &pdplConnectionSettings->pdp8HostAddress );
  370. if( FAILED( hr ) )
  371. {
  372. DPFX(DPFPREP, 0, "Error duplicating host address hr [0x%x]", hr );
  373. goto INITIALIZE_FAILED;
  374. }
  375. }
  376. if( pdplSettings->ppdp8DeviceAddresses )
  377. {
  378. pdplConnectionSettings->ppdp8DeviceAddresses = new PDIRECTPLAY8ADDRESS[pdplSettings->cNumDeviceAddresses];
  379. if( !pdplConnectionSettings->ppdp8DeviceAddresses )
  380. {
  381. hr = DPNERR_OUTOFMEMORY;
  382. DPFX(DPFPREP, 0, "Failed allocating memory" );
  383. goto INITIALIZE_FAILED;
  384. }
  385. for( DWORD dwIndex = 0; dwIndex < pdplSettings->cNumDeviceAddresses; dwIndex++ )
  386. {
  387. hr = pdplSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->Duplicate( pdplSettings->ppdp8DeviceAddresses[dwIndex], &pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex] );
  388. if( FAILED( hr ) )
  389. {
  390. DPFX(DPFPREP, 0, "Error duplicating host address hr [0x%x]", hr );
  391. goto INITIALIZE_FAILED;
  392. }
  393. }
  394. }
  395. if( pdplSettings->pwszPlayerName )
  396. {
  397. pdplConnectionSettings->pwszPlayerName = new WCHAR[wcslen(pdplSettings->pwszPlayerName)+1];
  398. if( !pdplConnectionSettings->pwszPlayerName )
  399. {
  400. DPFX(DPFPREP, 0, "Failed allocating memory" );
  401. hr = DPNERR_OUTOFMEMORY;
  402. goto INITIALIZE_FAILED;
  403. }
  404. wcscpy( pdplConnectionSettings->pwszPlayerName, pdplSettings->pwszPlayerName );
  405. }
  406. if( pdplSettings->dpnAppDesc.pwszSessionName )
  407. {
  408. pdplConnectionSettings->dpnAppDesc.pwszSessionName = new WCHAR[wcslen(pdplSettings->dpnAppDesc.pwszSessionName)+1];
  409. if( !pdplConnectionSettings->dpnAppDesc.pwszSessionName )
  410. {
  411. DPFX(DPFPREP, 0, "Failed allocating memory" );
  412. hr = DPNERR_OUTOFMEMORY;
  413. goto INITIALIZE_FAILED;
  414. }
  415. wcscpy( pdplConnectionSettings->dpnAppDesc.pwszSessionName, pdplSettings->dpnAppDesc.pwszSessionName );
  416. }
  417. if( pdplSettings->dpnAppDesc.pwszPassword )
  418. {
  419. pdplConnectionSettings->dpnAppDesc.pwszPassword = new WCHAR[wcslen(pdplSettings->dpnAppDesc.pwszPassword)+1];
  420. if( !pdplConnectionSettings->dpnAppDesc.pwszPassword )
  421. {
  422. DPFX(DPFPREP, 0, "Failed allocating memory" );
  423. hr = DPNERR_OUTOFMEMORY;
  424. goto INITIALIZE_FAILED;
  425. }
  426. wcscpy( pdplConnectionSettings->dpnAppDesc.pwszPassword, pdplSettings->dpnAppDesc.pwszPassword );
  427. }
  428. if( pdplSettings->dpnAppDesc.pvReservedData )
  429. {
  430. pdplConnectionSettings->dpnAppDesc.pvReservedData = new BYTE[pdplSettings->dpnAppDesc.dwReservedDataSize];
  431. if( !pdplConnectionSettings->dpnAppDesc.pvReservedData )
  432. {
  433. DPFX(DPFPREP, 0, "Failed allocating memory" );
  434. hr = DPNERR_OUTOFMEMORY;
  435. goto INITIALIZE_FAILED;
  436. }
  437. memcpy( pdplConnectionSettings->dpnAppDesc.pvReservedData,
  438. pdplSettings->dpnAppDesc.pvReservedData,
  439. pdplSettings->dpnAppDesc.dwReservedDataSize );
  440. }
  441. if( pdplSettings->dpnAppDesc.pvApplicationReservedData )
  442. {
  443. pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData = new BYTE[pdplSettings->dpnAppDesc.dwApplicationReservedDataSize];
  444. if( !pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData )
  445. {
  446. DPFX(DPFPREP, 0, "Failed allocating memory" );
  447. hr = DPNERR_OUTOFMEMORY;
  448. goto INITIALIZE_FAILED;
  449. }
  450. memcpy( pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData,
  451. pdplSettings->dpnAppDesc.pvApplicationReservedData,
  452. pdplSettings->dpnAppDesc.dwApplicationReservedDataSize );
  453. }
  454. // Free the old structure if one exists.
  455. if( m_fManaged )
  456. {
  457. m_fManaged = FALSE;
  458. }
  459. else if( m_pdplConnectionSettings )
  460. {
  461. FreeConnectionSettings( m_pdplConnectionSettings );
  462. }
  463. m_pdplConnectionSettings = pdplConnectionSettings;
  464. return DPN_OK;
  465. INITIALIZE_FAILED:
  466. FreeConnectionSettings( pdplConnectionSettings );
  467. return hr;
  468. }
  469. #undef DPF_MODNAME
  470. #define DPF_MODNAME "CConnectionSettings::BuildWireStruct"
  471. // BuildWireStruct
  472. //
  473. // This function fills the packed buffer with the wire representation of the
  474. // connection settings structure.
  475. HRESULT CConnectionSettings::BuildWireStruct( CPackedBuffer *const pPackedBuffer )
  476. {
  477. HRESULT hr = DPN_OK;
  478. DPL_INTERNAL_CONNECTION_SETTINGS *pdplConnectSettings = NULL;
  479. WCHAR *wszTmpAddress = NULL;
  480. DWORD dwTmpStringSize = 0;
  481. UNALIGNED DWORD *pdwTmpOffsets = NULL;
  482. UNALIGNED DWORD *pdwTmpLengths = NULL;
  483. pdplConnectSettings = (DPL_INTERNAL_CONNECTION_SETTINGS *) pPackedBuffer->GetHeadAddress();
  484. hr = pPackedBuffer->AddToFront( NULL, sizeof( DPL_INTERNAL_CONNECTION_SETTINGS ) );
  485. if( hr == DPN_OK )
  486. {
  487. ZeroMemory( pdplConnectSettings, sizeof( DPL_INTERNAL_CONNECTION_SETTINGS ) );
  488. //
  489. // COPY CORE FIXED VALUES
  490. //
  491. pdplConnectSettings->dwFlags = m_pdplConnectionSettings->dwFlags;
  492. pdplConnectSettings->dwNumDeviceAddresses = m_pdplConnectionSettings->cNumDeviceAddresses;
  493. //
  494. // COPY APPDESC FIXED VALUES
  495. //
  496. pdplConnectSettings->dpnApplicationDesc.dwSize = sizeof( DPN_APPLICATION_DESC_INFO );
  497. pdplConnectSettings->dpnApplicationDesc.dwFlags = m_pdplConnectionSettings->dpnAppDesc.dwFlags;
  498. pdplConnectSettings->dpnApplicationDesc.dwMaxPlayers = m_pdplConnectionSettings->dpnAppDesc.dwMaxPlayers;
  499. pdplConnectSettings->dpnApplicationDesc.dwCurrentPlayers = m_pdplConnectionSettings->dpnAppDesc.dwCurrentPlayers;
  500. pdplConnectSettings->dpnApplicationDesc.guidInstance = m_pdplConnectionSettings->dpnAppDesc.guidInstance;
  501. pdplConnectSettings->dpnApplicationDesc.guidApplication = m_pdplConnectionSettings->dpnAppDesc.guidApplication;
  502. }
  503. //
  504. // COPY VARIABLE CORE VALUES
  505. //
  506. if( m_pdplConnectionSettings->pwszPlayerName )
  507. {
  508. hr = pPackedBuffer->AddWCHARStringToBack( m_pdplConnectionSettings->pwszPlayerName );
  509. if( hr == DPN_OK && pdplConnectSettings )
  510. {
  511. pdplConnectSettings->dwPlayerNameOffset = pPackedBuffer->GetTailOffset();
  512. pdplConnectSettings->dwPlayerNameLength =
  513. (wcslen( m_pdplConnectionSettings->pwszPlayerName )+1) * sizeof( WCHAR );
  514. }
  515. }
  516. if( m_pdplConnectionSettings->pdp8HostAddress )
  517. {
  518. hr = m_pdplConnectionSettings->pdp8HostAddress->lpVtbl->GetURLW( m_pdplConnectionSettings->pdp8HostAddress, NULL, &dwTmpStringSize );
  519. if( hr != DPNERR_BUFFERTOOSMALL )
  520. {
  521. DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
  522. goto BUILDWIRESTRUCT_FAILURE;
  523. }
  524. wszTmpAddress = new WCHAR[dwTmpStringSize];
  525. if( !wszTmpAddress )
  526. {
  527. hr = DPNERR_OUTOFMEMORY;
  528. DPFX(DPFPREP, 0, "Failed allocating memory" );
  529. goto BUILDWIRESTRUCT_FAILURE;
  530. }
  531. hr = m_pdplConnectionSettings->pdp8HostAddress->lpVtbl->GetURLW( m_pdplConnectionSettings->pdp8HostAddress, wszTmpAddress, &dwTmpStringSize );
  532. if( FAILED( hr ) )
  533. {
  534. DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
  535. goto BUILDWIRESTRUCT_FAILURE;
  536. }
  537. hr = pPackedBuffer->AddWCHARStringToBack( wszTmpAddress );
  538. if( hr == DPN_OK && pdplConnectSettings )
  539. {
  540. pdplConnectSettings->dwHostAddressOffset = pPackedBuffer->GetTailOffset();
  541. pdplConnectSettings->dwHostAddressLength =
  542. (wcslen( wszTmpAddress )+1) * sizeof( WCHAR );
  543. }
  544. delete [] wszTmpAddress;
  545. wszTmpAddress = NULL;
  546. }
  547. hr = pPackedBuffer->AddToBack( NULL, sizeof( DWORD ) * m_pdplConnectionSettings->cNumDeviceAddresses );
  548. if( hr == DPN_OK && pdplConnectSettings )
  549. {
  550. pdwTmpOffsets = (DWORD *) pPackedBuffer->GetTailAddress();
  551. pdplConnectSettings->dwDeviceAddressOffset = pPackedBuffer->GetTailOffset();
  552. }
  553. hr = pPackedBuffer->AddToBack( NULL, sizeof( DWORD ) * m_pdplConnectionSettings->cNumDeviceAddresses );
  554. if( hr == DPN_OK && pdplConnectSettings )
  555. {
  556. pdwTmpLengths = (DWORD *) pPackedBuffer->GetTailAddress();
  557. pdplConnectSettings->dwDeviceAddressLengthOffset = pPackedBuffer->GetTailOffset();
  558. }
  559. for( DWORD dwIndex = 0; dwIndex < m_pdplConnectionSettings->cNumDeviceAddresses; dwIndex++ )
  560. {
  561. dwTmpStringSize = 0;
  562. hr = m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->GetURLW(
  563. m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex],
  564. NULL, &dwTmpStringSize );
  565. if( hr != DPNERR_BUFFERTOOSMALL )
  566. {
  567. DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
  568. goto BUILDWIRESTRUCT_FAILURE;
  569. }
  570. wszTmpAddress = new WCHAR[dwTmpStringSize];
  571. if( !wszTmpAddress )
  572. {
  573. hr = DPNERR_OUTOFMEMORY;
  574. DPFX(DPFPREP, 0, "Failed allocating memory" );
  575. goto BUILDWIRESTRUCT_FAILURE;
  576. }
  577. hr = m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->GetURLW(
  578. m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex],
  579. wszTmpAddress, &dwTmpStringSize );
  580. if( FAILED( hr ) )
  581. {
  582. DPFX(DPFPREP, 0, "Failed converting address hr [0x%x]", hr );
  583. goto BUILDWIRESTRUCT_FAILURE;
  584. }
  585. hr = pPackedBuffer->AddWCHARStringToBack( wszTmpAddress );
  586. if( hr == DPN_OK && pdplConnectSettings && pdwTmpLengths )
  587. {
  588. pdwTmpOffsets[dwIndex] = pPackedBuffer->GetTailOffset();
  589. pdwTmpLengths[dwIndex] = (wcslen( wszTmpAddress )+1) * sizeof( WCHAR );
  590. }
  591. delete [] wszTmpAddress;
  592. wszTmpAddress = NULL;
  593. }
  594. //
  595. // COPY APP DESC VARIABLE MEMBERS
  596. //
  597. if( m_pdplConnectionSettings->dpnAppDesc.pwszPassword )
  598. {
  599. hr = pPackedBuffer->AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszPassword );
  600. if( hr == DPN_OK && pdplConnectSettings )
  601. {
  602. pdplConnectSettings->dpnApplicationDesc.dwPasswordOffset = pPackedBuffer->GetTailOffset();
  603. pdplConnectSettings->dpnApplicationDesc.dwPasswordSize =
  604. (wcslen( m_pdplConnectionSettings->dpnAppDesc.pwszPassword )+1) * sizeof( WCHAR );
  605. }
  606. }
  607. if( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName)
  608. {
  609. hr = pPackedBuffer->AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName );
  610. if( hr == DPN_OK && pdplConnectSettings )
  611. {
  612. pdplConnectSettings->dpnApplicationDesc.dwSessionNameOffset = pPackedBuffer->GetTailOffset();
  613. pdplConnectSettings->dpnApplicationDesc.dwSessionNameSize =
  614. (wcslen( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName )+1) * sizeof( WCHAR );
  615. }
  616. }
  617. if( m_pdplConnectionSettings->dpnAppDesc.pvReservedData )
  618. {
  619. hr = pPackedBuffer->AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvReservedData,
  620. m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize );
  621. if( hr == DPN_OK && pdplConnectSettings )
  622. {
  623. pdplConnectSettings->dpnApplicationDesc.dwReservedDataOffset = pPackedBuffer->GetTailOffset();
  624. pdplConnectSettings->dpnApplicationDesc.dwReservedDataSize = m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize;
  625. }
  626. }
  627. if( m_pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData)
  628. {
  629. hr = pPackedBuffer->AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData,
  630. m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize);
  631. if( hr == DPN_OK && pdplConnectSettings )
  632. {
  633. pdplConnectSettings->dpnApplicationDesc.dwApplicationReservedDataOffset = pPackedBuffer->GetTailOffset();
  634. pdplConnectSettings->dpnApplicationDesc.dwApplicationReservedDataSize = m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize;
  635. }
  636. }
  637. BUILDWIRESTRUCT_FAILURE:
  638. if( wszTmpAddress )
  639. delete [] wszTmpAddress;
  640. return hr;
  641. }
  642. #undef DPF_MODNAME
  643. #define DPF_MODNAME "CConnectionSettings::SetEqual"
  644. // SetEqual
  645. //
  646. // This function provides a deep copy of the specified class into this object
  647. HRESULT CConnectionSettings::SetEqual( CConnectionSettings * pdplSettings )
  648. {
  649. PDPL_CONNECTION_SETTINGS pConnectSettings = pdplSettings->GetConnectionSettings();
  650. if( pConnectSettings == NULL )
  651. {
  652. DPFX(DPFPREP, 0, "Error getting settings -- no settings available!" );
  653. return DPNERR_DOESNOTEXIST;
  654. }
  655. return Initialize( pConnectSettings );
  656. }
  657. #undef DPF_MODNAME
  658. #define DPF_MODNAME "CConnectionSettings::CopyToBuffer( BYTE *pbBuffer, DWORD *pdwBufferSize )"
  659. HRESULT CConnectionSettings::CopyToBuffer( BYTE *pbBuffer, DWORD *pdwBufferSize )
  660. {
  661. if( m_pdplConnectionSettings == NULL )
  662. {
  663. *pdwBufferSize = 0;
  664. return DPNERR_DOESNOTEXIST;
  665. }
  666. CPackedBuffer packBuff;
  667. HRESULT hr = DPN_OK;
  668. DPL_CONNECTION_SETTINGS *pConnectionSettings = NULL;
  669. packBuff.Initialize( pbBuffer, *pdwBufferSize, TRUE );
  670. pConnectionSettings = (DPL_CONNECTION_SETTINGS *) packBuff.GetHeadAddress();
  671. hr = packBuff.AddToFront( m_pdplConnectionSettings, sizeof( DPL_CONNECTION_SETTINGS ), TRUE );
  672. if( FAILED( hr ) )
  673. {
  674. pConnectionSettings = NULL;
  675. }
  676. // Add app desc's session name if there is one
  677. if( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName != NULL )
  678. {
  679. hr = packBuff.AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszSessionName, TRUE );
  680. if( pConnectionSettings )
  681. pConnectionSettings->dpnAppDesc.pwszSessionName = (WCHAR *) packBuff.GetTailAddress();
  682. }
  683. // Copy player name
  684. if( m_pdplConnectionSettings->pwszPlayerName != NULL )
  685. {
  686. hr = packBuff.AddWCHARStringToBack( m_pdplConnectionSettings->pwszPlayerName, TRUE );
  687. if( pConnectionSettings )
  688. pConnectionSettings->pwszPlayerName = (WCHAR *) packBuff.GetTailAddress();
  689. }
  690. // Copy password
  691. if( m_pdplConnectionSettings->dpnAppDesc.pwszPassword )
  692. {
  693. hr = packBuff.AddWCHARStringToBack( m_pdplConnectionSettings->dpnAppDesc.pwszPassword, TRUE );
  694. if( pConnectionSettings )
  695. pConnectionSettings->dpnAppDesc.pwszPassword = (WCHAR *) packBuff.GetTailAddress();
  696. }
  697. if( m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize )
  698. {
  699. hr = packBuff.AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvReservedData, m_pdplConnectionSettings->dpnAppDesc.dwReservedDataSize, TRUE );
  700. if( pConnectionSettings )
  701. pConnectionSettings->dpnAppDesc.pvReservedData = (WCHAR *) packBuff.GetTailAddress();
  702. }
  703. if( m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize )
  704. {
  705. hr = packBuff.AddToBack( m_pdplConnectionSettings->dpnAppDesc.pvApplicationReservedData, m_pdplConnectionSettings->dpnAppDesc.dwApplicationReservedDataSize, TRUE );
  706. if( pConnectionSettings )
  707. pConnectionSettings->dpnAppDesc.pvApplicationReservedData = (WCHAR *) packBuff.GetTailAddress();
  708. }
  709. hr = packBuff.AddToBack( m_pdplConnectionSettings->ppdp8DeviceAddresses, sizeof( IDirectPlay8Address * )*m_pdplConnectionSettings->cNumDeviceAddresses, TRUE );
  710. if( pConnectionSettings )
  711. pConnectionSettings->ppdp8DeviceAddresses = (IDirectPlay8Address **) packBuff.GetTailAddress();
  712. if( pConnectionSettings )
  713. {
  714. if( m_pdplConnectionSettings->pdp8HostAddress != NULL )
  715. {
  716. hr = m_pdplConnectionSettings->pdp8HostAddress->lpVtbl->Duplicate( m_pdplConnectionSettings->pdp8HostAddress, &pConnectionSettings->pdp8HostAddress );
  717. if( FAILED( hr ) )
  718. {
  719. DPFX(DPFPREP, 0, "Error duplicating host address hr [0x%x]", hr );
  720. goto INITIALIZE_COMPLETE;
  721. }
  722. }
  723. for( DWORD dwIndex = 0; dwIndex < m_pdplConnectionSettings->cNumDeviceAddresses; dwIndex++ )
  724. {
  725. hr = m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex]->lpVtbl->Duplicate( m_pdplConnectionSettings->ppdp8DeviceAddresses[dwIndex], &pConnectionSettings->ppdp8DeviceAddresses[dwIndex] );
  726. if( FAILED( hr ) )
  727. {
  728. DPFX(DPFPREP, 0, "Error duplicating device address hr [0x%x]", hr );
  729. goto INITIALIZE_COMPLETE;
  730. }
  731. }
  732. }
  733. INITIALIZE_COMPLETE:
  734. *pdwBufferSize = packBuff.GetSizeRequired();
  735. return hr;
  736. }