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.

2241 lines
62 KiB

  1. // =================================================================
  2. //
  3. // Direct Play Network Methods
  4. //
  5. // Functions to manage communications over a network.
  6. //
  7. //
  8. // =================================================================
  9. #ifndef WIN32_LEAN_AND_MEAN
  10. #define WIN32_LEAN_AND_MEAN
  11. #endif
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <winsock.h>
  15. #ifndef _MT
  16. #define _MT
  17. #endif
  18. #include <process.h>
  19. #include <string.h>
  20. #include "dpspimp.h"
  21. #include "logit.h"
  22. #include "tapicode.h"
  23. #include "commcode.h"
  24. #include "resource.h"
  25. extern volatile BOOL g_bIgnoreReads;
  26. extern volatile BOOL g_bRecovery;
  27. extern volatile BOOL g_bCommStarted;
  28. extern "C" HINSTANCE hInst;
  29. extern volatile DWORD g_dwRate;
  30. extern BOOL g_bCallCancel;
  31. #define malloc(a) LocalAlloc(LMEM_FIXED, (a))
  32. #define free(a) LocalFree((HLOCAL)(a))
  33. CImpIDP_SP *pDirectPlayObject = NULL; // We only allow one object
  34. // to be created currently - see below.
  35. HANDLE hOnlyOneAllowed = NULL;
  36. extern CImpIDP_SP *g_IDP;
  37. extern BOOL CreateQueue(DWORD dwElements, DWORD dwMaxMsg, DWORD dwMaxPlayers);
  38. extern BOOL DeleteQueue();
  39. GUID DPLAY_MODEM = { /* 8cab4652-b1b6-11ce-920c-00aa006c4972 */
  40. 0x8cab4652,
  41. 0xb1b6,
  42. 0x11ce,
  43. {0x92, 0x0c, 0x00, 0xaa, 0x00, 0x6c, 0x49, 0x72}
  44. };
  45. BOOL g_bPostHangup = FALSE;
  46. DWORD WINAPI StartTapiThreadProc(LPVOID lpvParam)
  47. {
  48. HANDLE hEvent = (LPHANDLE) lpvParam;
  49. MSG msg;
  50. CImpIDP_SP *pIDP = NULL;
  51. BOOL bShutdown = FALSE;
  52. if (hEvent == NULL)
  53. return(0);
  54. if (! InitializeTAPI(NULL))
  55. return(NULL);
  56. SetEvent(hEvent);
  57. while(!bShutdown && GetMessage(&msg, NULL, 0, 0) )
  58. {
  59. switch (msg.message)
  60. {
  61. case PWM_SETIDP:
  62. pIDP = (CImpIDP_SP *) msg.wParam;
  63. break;
  64. case PWM_CLOSE:
  65. TSHELL_INFO(TEXT("Close requested."));
  66. bShutdown = TRUE;
  67. break;
  68. case PWM_HANGUP:
  69. TSHELL_INFO(TEXT("Hangup Requested"));
  70. pIDP->m_bConnected = FALSE;
  71. pIDP->m_bPlayer0 = FALSE;
  72. g_bIgnoreReads = FALSE;
  73. pIDP->DeleteRemotePlayers();
  74. pIDP->ResetSessionDesc();
  75. if (!HangupCallI())
  76. {
  77. TSHELL_INFO(TEXT("HangupCall failed."));
  78. bShutdown = TRUE;
  79. }
  80. g_bPostHangup = FALSE;
  81. TSHELL_INFO(TEXT("Hangup Finished."));
  82. break;
  83. default:
  84. TranslateMessage(&msg);
  85. DispatchMessage(&msg);
  86. break;
  87. }
  88. }
  89. TSHELL_INFO( TEXT("Exit StartThreadTapi Loop. "));
  90. ShutdownTAPI();
  91. TSHELL_INFO(TEXT("StartThreadTapi exits."));
  92. return(0);
  93. }
  94. //
  95. // FUNCTION: PostHangupCall()
  96. //
  97. // PURPOSE: Posts a message to the main TAPI thread to hangup the call.
  98. //
  99. // PARAMETERS:
  100. // none
  101. //
  102. // RETURN VALUE:
  103. // none
  104. //
  105. // COMMENTS:
  106. //
  107. // TAPI is thread specific, meaning that only the thread that does the
  108. // lineInitialize can get asynchronous messages through the callback.
  109. // Since the HangupCall can potentially go into a loop waiting for
  110. // specific events, any other threads that call HangupCall can cause
  111. // timing confusion. Best to just have other threads 'ask' the main thread
  112. // to hangup the call.
  113. //
  114. void PostHangupCall()
  115. {
  116. if (g_IDP)
  117. g_IDP->PostHangup();
  118. else
  119. HangupCall(__LINE__);
  120. }
  121. HRESULT CImpIDP_SP::Initialize(LPGUID lpiid)
  122. {
  123. TSHELL_INFO(TEXT("Already Initialized."));
  124. return(DPERR_ALREADYINITIALIZED);
  125. }
  126. void *CImpIDP_SP::operator new( size_t size )
  127. {
  128. return(LocalAlloc(LMEM_FIXED, size));
  129. }
  130. void CImpIDP_SP::operator delete( void *ptr )
  131. {
  132. LocalFree((HLOCAL)ptr);
  133. }
  134. VOID CImpIDP_SP::PostHangup()
  135. {
  136. g_bPostHangup = TRUE;
  137. if (m_dwTapiThreadID)
  138. PostThreadMessage( m_dwTapiThreadID, PWM_HANGUP, 0, 0);
  139. }
  140. CImpIDP_SP *CImpIDP_SP::NewCImpIDP_SP()
  141. {
  142. CImpIDP_SP *pImp = NULL;
  143. HANDLE hEvent = NULL;
  144. HANDLE hTapiThread = NULL;
  145. DWORD dwTapiThreadID;
  146. DWORD dwRet1;
  147. DWORD dwRet2;
  148. g_bIgnoreReads = FALSE;
  149. if (g_IDP)
  150. return(NULL);
  151. if (!CreateQueue(64, MAX_MSG, MAX_PLAYERS))
  152. {
  153. TSHELL_INFO(TEXT("Couldn't initialize queue."));
  154. return(NULL);
  155. }
  156. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  157. if (!hEvent)
  158. return(NULL);
  159. pImp = new CImpIDP_SP;
  160. if (!pImp)
  161. return(NULL);
  162. hTapiThread = CreateThread(NULL, 0, StartTapiThreadProc,
  163. (LPVOID) hEvent, 0, &dwTapiThreadID);
  164. if (!hTapiThread)
  165. {
  166. delete pImp;
  167. return(NULL);
  168. }
  169. dwRet1 = WaitForSingleObject(hEvent, 10000);
  170. CloseHandle(hEvent);
  171. dwRet2 = WaitForSingleObject(hTapiThread, 0);
  172. if (dwRet1 == WAIT_TIMEOUT || dwRet2 != WAIT_TIMEOUT)
  173. {
  174. if (dwRet2 == WAIT_TIMEOUT)
  175. {
  176. TerminateThread(hTapiThread, 0);
  177. Sleep(200);
  178. }
  179. CloseHandle(hTapiThread);
  180. delete pImp;
  181. return(NULL);
  182. }
  183. PostThreadMessage( dwTapiThreadID, PWM_SETIDP, (WPARAM) pImp, 0);
  184. pImp->m_dpcaps.dwMaxBufferSize = 512;
  185. pImp->m_hTapiThread = hTapiThread;
  186. pImp->m_dwTapiThreadID = dwTapiThreadID;
  187. g_IDP = pImp;
  188. return(pImp);
  189. }
  190. // ----------------------------------------------------------
  191. // CreateNewDirectPlay - DCO object creation entry point
  192. // called by the DCO interface functions to create a new
  193. // DCO object.
  194. // ----------------------------------------------------------
  195. IDirectPlaySP * _cdecl CreateNewDirectPlay( LPGUID lpGuid )
  196. {
  197. //
  198. // One object at a time, please.
  199. //
  200. if (pDirectPlayObject != NULL || hOnlyOneAllowed != NULL)
  201. return(NULL);
  202. hOnlyOneAllowed = CreateEvent(NULL, TRUE, TRUE, "DPSERIAL_UNIQUE");
  203. if (hOnlyOneAllowed == NULL)
  204. return(NULL);
  205. else
  206. {
  207. if (GetLastError() == ERROR_ALREADY_EXISTS)
  208. {
  209. TSHELL_INFO(TEXT("Someone tried to run 2 modems!"));
  210. CloseHandle(hOnlyOneAllowed);
  211. hOnlyOneAllowed = NULL;
  212. return(NULL);
  213. }
  214. }
  215. if (! IsEqualGUID((REFGUID) DPLAY_MODEM, (REFGUID) *lpGuid))
  216. return(NULL);
  217. //
  218. // The network service provider doesn't support more than 1
  219. // Guid, so we do nothing.
  220. //
  221. lpGuid;
  222. pDirectPlayObject = CImpIDP_SP::NewCImpIDP_SP();
  223. if (!pDirectPlayObject)
  224. return(NULL);
  225. else
  226. return(pDirectPlayObject);
  227. }
  228. // Begin: IUnknown interface implementation
  229. HRESULT CImpIDP_SP::QueryInterface(
  230. REFIID iid,
  231. LPVOID *ppvObj
  232. )
  233. {
  234. HRESULT retVal = DPERR_GENERIC;
  235. //
  236. // BUGBUG
  237. //
  238. if (ppvObj && ! IsBadWritePtr(ppvObj, 4))
  239. {
  240. AddRef();
  241. *ppvObj = this;
  242. return(DP_OK);
  243. }
  244. else
  245. return(DPERR_INVALIDPARAM);
  246. }
  247. ULONG CImpIDP_SP::AddRef( void)
  248. {
  249. ULONG newRefCount;
  250. Lock();
  251. m_refCount++;
  252. newRefCount = m_refCount;
  253. Unlock();
  254. DBG_INFO((DBGARG, TEXT("newRefCount = %lu"), newRefCount));
  255. return( newRefCount );
  256. }
  257. ULONG CImpIDP_SP::Release( void )
  258. {
  259. ULONG newRefCount;
  260. DWORD ii;
  261. DWORD dwTime = 0;
  262. #ifdef DEBUG
  263. DWORD dwTickCount = GetTickCount();
  264. #endif
  265. Lock();
  266. m_refCount--;
  267. newRefCount = m_refCount;
  268. Unlock();
  269. if (newRefCount == 0)
  270. {
  271. Close(DPLAY_CLOSE_INTERNAL);
  272. if (m_dwTapiThreadID && m_hTapiThread)
  273. {
  274. while (m_hTapiThread && dwTime < 4000)
  275. {
  276. PostThreadMessage( m_dwTapiThreadID, PWM_CLOSE, 0, 0);
  277. if (WaitForSingleObject(m_hTapiThread, 100) == WAIT_TIMEOUT)
  278. {
  279. dwTime += 100;
  280. }
  281. else
  282. {
  283. CloseHandle(m_hTapiThread);
  284. m_hTapiThread = NULL;
  285. }
  286. }
  287. }
  288. if (m_ppSessionArray)
  289. {
  290. for (ii = 0; ii < m_dwSessionPrev; ii++)
  291. free(m_ppSessionArray[ii]);
  292. free(m_ppSessionArray);
  293. }
  294. if (m_hTapiThread && WaitForSingleObject(m_hTapiThread, 100) == WAIT_TIMEOUT)
  295. {
  296. TSHELL_INFO(TEXT("Terminate Thread."));
  297. TerminateThread(m_hTapiThread, 0);
  298. Sleep(200);
  299. CloseHandle(m_hTapiThread);
  300. }
  301. DeleteCriticalSection(&m_critSection);
  302. DeleteQueue();
  303. g_IDP = NULL;
  304. hInst = NULL;
  305. pDirectPlayObject = NULL;
  306. DBG_INFO((DBGARG, TEXT("Total close time %d"), GetTickCount() - dwTickCount));
  307. delete this;
  308. pDirectPlayObject = NULL;
  309. CloseHandle(hOnlyOneAllowed);
  310. hOnlyOneAllowed = NULL;
  311. }
  312. DBG_INFO((DBGARG, TEXT("newRefCount = %lu"), newRefCount));
  313. return( newRefCount );
  314. }
  315. // End : IUnknown interface implementation
  316. // ----------------------------------------------------------
  317. // CImpIDP_SP constructor - create a new DCO object
  318. // along with a queue of receive buffers.
  319. // ----------------------------------------------------------
  320. CImpIDP_SP::CImpIDP_SP()
  321. {
  322. m_bConnected = FALSE;
  323. m_bPlayer0 = FALSE;
  324. m_dwPendingWrites = 0;
  325. m_dwPingSent = 0;
  326. m_hBlockingEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  327. m_dwNextPlayer = 1;
  328. m_bEnablePlayerAdd = TRUE;
  329. memset(&m_aPlayer[0], 0x00, sizeof(PLAYER_RECORD) * MAX_PLAYERS);
  330. m_lpDisplay[0] = 0x00;
  331. m_lpDialable[0] = 0x00;
  332. m_dwID = 0;
  333. m_iPlayerIndex = -1;
  334. memset(&m_dpDesc, 0x00, sizeof(DPSESSIONDESC));
  335. // Initialize ref count
  336. m_refCount = 1;
  337. InitializeCriticalSection( &m_critSection );
  338. memset(&m_dpcaps, 0x00, sizeof(DPCAPS));
  339. m_dpcaps.dwSize = sizeof(DPCAPS);
  340. m_dpcaps.dwFlags = 0;
  341. m_dpcaps.dwMaxQueueSize = 64;
  342. m_dpcaps.dwMaxPlayers = MAX_PLAYERS;
  343. m_dpcaps.dwHundredBaud = 0;
  344. m_hNewPlayerEvent = NULL;
  345. m_hTapiThread = NULL;
  346. m_dwTapiThreadID = 0;
  347. m_ppSessionArray = 0;
  348. m_dwSessionPrev = 0;
  349. m_dwSessionAlloc = 0;
  350. }
  351. // ----------------------------------------------------------
  352. // CImpDirectPlay destructor -
  353. // ----------------------------------------------------------
  354. CImpIDP_SP::~CImpIDP_SP()
  355. {
  356. TSHELL_INFO(TEXT("Deletion."));
  357. }
  358. void CImpIDP_SP::Lock( void )
  359. {
  360. EnterCriticalSection( &m_critSection );
  361. }
  362. void CImpIDP_SP::Unlock( void )
  363. {
  364. LeaveCriticalSection( &m_critSection );
  365. }
  366. // ----------------------------------------------------------
  367. // GetCaps - return info about the connection media
  368. // ----------------------------------------------------------
  369. //
  370. // Return our caps immediately if we have a valid latency value.
  371. // if we haven't gotten latency yet, send a DPSYS_PING. Latency is
  372. // the time it takes to get a response DPSYS_PING / 2.
  373. //
  374. HRESULT CImpIDP_SP::GetCaps(
  375. LPDPCAPS lpDPCaps // buffer to receive capabilities
  376. )
  377. {
  378. m_dpcaps.dwHundredBaud = g_dwRate / 100;
  379. *lpDPCaps = m_dpcaps;
  380. if (m_dpcaps.dwLatency == 0)
  381. SendPing();
  382. return(DP_OK);
  383. }
  384. // ----------------------------------------------------------
  385. // Connect - establishes communications with underlying transport,
  386. // and initializes name services and network entities
  387. // ----------------------------------------------------------
  388. BOOL CImpIDP_SP::SetSession(DWORD dw)
  389. {
  390. m_lpDisplay[0] = 0x00;
  391. if (dw == 0)
  392. {
  393. m_lpDialable[0] = 0x00;
  394. return(TRUE);
  395. }
  396. else
  397. {
  398. dw--;
  399. if (dw >= m_dwSessionPrev)
  400. return(FALSE);
  401. lstrcpy( m_lpDialable, (m_ppSessionArray[dw] + sizeof(dw)));
  402. lstrcpy( m_lpDisplay, (m_ppSessionArray[dw] + sizeof(dw)));
  403. DBG_INFO((DBGARG, TEXT("Got %s for dialable string."), m_lpDialable));
  404. return(TRUE);
  405. }
  406. }
  407. HRESULT CImpIDP_SP::Open(
  408. LPDPSESSIONDESC lpSDesc, HANDLE lpHandle
  409. )
  410. {
  411. DWORD ii;
  412. SPMSG_CONNECT *pMsg;
  413. TSHELL_INFO(TEXT("SP Open"));
  414. for (ii = 0; ii < MAX_PLAYERS; ii++)
  415. {
  416. if (m_aPlayer[ii].bValid )
  417. {
  418. TSHELL_INFO(TEXT("Illegal player found, return error."));
  419. return(DPERR_ACTIVEPLAYERS);
  420. }
  421. }
  422. if (lpSDesc->dwFlags & DPOPEN_CREATESESSION)
  423. {
  424. TSHELL_INFO(TEXT("Place machine in Recieve mode."));
  425. if (ReceiveCall())
  426. {
  427. m_bPlayer0 = TRUE;
  428. memcpy( (LPVOID) &m_dpDesc, lpSDesc, sizeof(DPSESSIONDESC));
  429. m_dpDesc.dwCurrentPlayers = 0;
  430. m_dpDesc.dwReserved1 = 0;
  431. m_dpDesc.dwReserved2 = 0;
  432. return(DP_OK);
  433. }
  434. else
  435. return(DPERR_GENERIC);
  436. }
  437. else if (lpSDesc->dwFlags & DPOPEN_OPENSESSION)
  438. {
  439. TSHELL_INFO(TEXT("Open a session."));
  440. if (!SetSession(lpSDesc->dwSession))
  441. return(DPERR_GENERIC);
  442. TSHELL_INFO(TEXT("Dial call."));
  443. g_bIgnoreReads = TRUE;
  444. ResetEvent(m_hBlockingEvent);
  445. if (DialCall(m_lpDisplay, m_lpDialable, &m_dwID, m_hBlockingEvent))
  446. {
  447. TSHELL_INFO(TEXT("DialCall Succeeded."));
  448. if ( WaitForSingleObject(m_hBlockingEvent, 60000) == WAIT_TIMEOUT
  449. || !g_bCommStarted)
  450. {
  451. TSHELL_INFO(TEXT("Timeout waiting for connection."));
  452. return(DPERR_NOCONNECTION);
  453. }
  454. TSHELL_INFO(TEXT("No messages sent yet."));
  455. Sleep(1000);
  456. g_bIgnoreReads = FALSE;
  457. TSHELL_INFO(TEXT("Now try and connect."));
  458. ResetEvent(m_hBlockingEvent);
  459. //
  460. // Send connection protocol messages.
  461. //
  462. for (ii = 0; (ii < 10)
  463. && !m_bConnected
  464. && !g_bRecovery
  465. && g_bCommStarted; ii++)
  466. {
  467. pMsg = (SPMSG_CONNECT *) malloc(sizeof(SPMSG_CONNECT));
  468. pMsg->dpHdr.to = 0;
  469. pMsg->dpHdr.from = 0;
  470. pMsg->dpHdr.usCount = sizeof(SPMSG_CONNECT) - sizeof(DPHDR);
  471. pMsg->dpHdr.usCookie = SPSYS_CONNECT;
  472. pMsg->usVerMajor = DPVERSION_MAJOR;
  473. pMsg->usVerMinor = DPVERSION_MINOR;
  474. pMsg->dwConnect1 = DPSYS_KYRA;
  475. pMsg->dwConnect2 = DPSYS_HALL;
  476. // TSHELL_INFO(TEXT("Write Connection Msg."));
  477. g_bIgnoreReads = FALSE;
  478. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_CONNECT));
  479. WaitForSingleObject(m_hBlockingEvent, 6000);
  480. if (g_bRecovery)
  481. {
  482. TSHELL_INFO(TEXT("Open Generated recovery problem."));
  483. ResetEvent(m_hBlockingEvent);
  484. WaitForSingleObject(m_hBlockingEvent, 10000);
  485. }
  486. if (g_bRecovery)
  487. {
  488. TSHELL_INFO(TEXT("Open Still has recovery problem, give up."));
  489. }
  490. }
  491. if (m_bConnected && m_dpDesc.dwMaxPlayers != 0)
  492. {
  493. TSHELL_INFO(TEXT("Connection Made."));
  494. DBG_INFO((DBGARG, TEXT("Current Players. %d"), m_dpDesc.dwCurrentPlayers));
  495. SendPing();
  496. return(DP_OK);
  497. }
  498. else
  499. {
  500. TSHELL_INFO(TEXT("Connection timed out"));
  501. Close(0);
  502. return(DPERR_NOCONNECTION);
  503. }
  504. }
  505. else
  506. {
  507. if (g_bCallCancel)
  508. return(DPERR_USERCANCEL);
  509. TSHELL_INFO(TEXT("DialCall failed."));
  510. return(DPERR_GENERIC);
  511. }
  512. }
  513. else
  514. {
  515. TSHELL_INFO(TEXT("Unhandled Open flags."));
  516. return(DPERR_UNSUPPORTED);
  517. }
  518. }
  519. // ----------------------------------------------------------
  520. // CreatePlayer - registers new player, N.B. may fail if
  521. // not currently connected to name server
  522. // ----------------------------------------------------------
  523. LONG CImpIDP_SP::FindInvalidIndex()
  524. {
  525. DWORD ii;
  526. for (ii = 0; ii < MAX_PLAYERS; ii++)
  527. if (m_aPlayer[ii].bValid == FALSE)
  528. return(ii);
  529. return(-1);
  530. }
  531. VOID CImpIDP_SP::LocalMsg(LONG iIndex, LPVOID lpv, DWORD dwSize)
  532. {
  533. LONG ii;
  534. for (ii = 0; ii < MAX_PLAYERS; ii++)
  535. if ( ii != iIndex
  536. && m_aPlayer[ii].bValid
  537. && m_aPlayer[ii].bLocal
  538. && m_aPlayer[ii].bPlayer)
  539. AddMessage(lpv, dwSize, m_aPlayer[ii].pid, 0, 0);
  540. }
  541. VOID CImpIDP_SP::RemoteMsg(LONG iIndex, LPVOID lpv, DWORD dwSize)
  542. {
  543. SPMSG_GENERIC *pMsg;
  544. DWORD dwTotal = dwSize + sizeof(DPHDR);
  545. pMsg = (SPMSG_GENERIC *) malloc(dwTotal);
  546. if (pMsg)
  547. {
  548. pMsg->dpHdr.usCookie = SPSYS_SYS;
  549. pMsg->dpHdr.to = 0;
  550. pMsg->dpHdr.from = 0;
  551. pMsg->dpHdr.usCount = (USHORT) dwSize;
  552. memcpy( (LPVOID) &pMsg->sMsg, lpv, dwSize);
  553. WriteCommString( (LPVOID) pMsg, dwTotal);
  554. }
  555. }
  556. extern BOOL SetupLocalPlayer(DPID pid, HANDLE hEvent);
  557. HRESULT CImpIDP_SP::CreatePlayer(
  558. LPDPID pPlayerID,
  559. LPSTR pNickName,
  560. LPSTR pFullName,
  561. LPHANDLE lpReceiveEvent,
  562. BOOL bPlayer
  563. )
  564. {
  565. DWORD ii, jj;
  566. SPMSG_ADDPLAYER *pMsg;
  567. HANDLE hEvent = NULL;
  568. BOOL bb = TRUE;
  569. HRESULT hr = DP_OK;
  570. LONG iIndex;
  571. DPMSG_ADDPLAYER dpAdd;
  572. // TSHELL_INFO(TEXT("Enter Create Player"));
  573. if (m_dwNextPlayer > MAXIMUM_PLAYER_ID)
  574. {
  575. return(DPERR_CANTCREATEPLAYER);
  576. }
  577. if (m_bConnected == FALSE)
  578. if (m_bPlayer0 != TRUE)
  579. return(DPERR_NOCONNECTION);
  580. if (m_bEnablePlayerAdd == FALSE && bPlayer == TRUE)
  581. return(DPERR_CANTCREATEPLAYER);
  582. if (m_dpDesc.dwMaxPlayers == m_dpDesc.dwCurrentPlayers)
  583. {
  584. DBG_INFO((DBGARG, TEXT("CreatePlayer: at max players already. %d"),
  585. m_dpDesc.dwMaxPlayers));
  586. return(DPERR_CANTADDPLAYER);
  587. }
  588. if (m_iPlayerIndex != -1)
  589. {
  590. TSHELL_INFO(TEXT("Player index not -1, create already in progress."));
  591. return(DPERR_GENERIC);
  592. }
  593. iIndex = FindInvalidIndex();
  594. if (iIndex == -1)
  595. return(DPERR_GENERIC);
  596. if (m_hNewPlayerEvent)
  597. return(DPERR_GENERIC);
  598. if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
  599. {
  600. TSHELL_INFO(TEXT("CreatePlayer: CreateEvent failure."));
  601. return(DPERR_GENERIC);
  602. }
  603. else
  604. {
  605. ; // DBG_INFO((DBGARG, TEXT("CreatePlayer %8x Event"), hEvent));
  606. }
  607. dpAdd.dwType = DPSYS_ADDPLAYER;
  608. dpAdd.dwPlayerType = bPlayer;
  609. dpAdd.dpId = 0;
  610. lstrcpy( dpAdd.szShortName, pNickName);
  611. lstrcpy( dpAdd.szLongName , pFullName);
  612. if (m_bPlayer0)
  613. {
  614. m_dpDesc.dwCurrentPlayers++;
  615. m_aPlayer[iIndex].pid = (DPID) m_dwNextPlayer++;
  616. lstrcpy( m_aPlayer[iIndex].chNickName, pNickName);
  617. lstrcpy( m_aPlayer[iIndex].chFullName, pFullName);
  618. m_aPlayer[iIndex].bValid = TRUE;
  619. m_aPlayer[iIndex].bPlayer = bPlayer;
  620. m_aPlayer[iIndex].hEvent = hEvent;
  621. m_aPlayer[iIndex].bLocal = TRUE;
  622. for (ii = 0; ii < MAX_PLAYERS; ii++)
  623. m_aPlayer[iIndex].aGroup[ii] = 0;
  624. dpAdd.dpId = m_aPlayer[iIndex].pid;
  625. LocalMsg( iIndex, (LPVOID) &dpAdd, sizeof(DPMSG_ADDPLAYER));
  626. RemoteMsg(iIndex, (LPVOID) &dpAdd, sizeof(DPMSG_ADDPLAYER));
  627. hEvent = NULL;
  628. *pPlayerID = (DPID) (0x0000ffff & m_aPlayer[iIndex].pid);
  629. if (lpReceiveEvent)
  630. *lpReceiveEvent = m_aPlayer[iIndex].hEvent;
  631. SetupLocalPlayer(m_aPlayer[iIndex].pid, m_aPlayer[iIndex].hEvent);
  632. return(DP_OK);
  633. }
  634. m_hNewPlayerEvent = hEvent;
  635. for (jj = 0; jj < 3; jj++)
  636. {
  637. pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
  638. if (pMsg)
  639. {
  640. TSHELL_INFO(TEXT("Prepare AddPlayer message"));
  641. pMsg->dpHdr.usCookie = SPSYS_SYS;
  642. pMsg->dpHdr.to = 0;
  643. pMsg->dpHdr.from = 0;
  644. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  645. memcpy( (LPVOID) &pMsg->sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
  646. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
  647. pMsg = NULL;
  648. if (WaitForSingleObject(m_hNewPlayerEvent, 4500) != WAIT_TIMEOUT)
  649. {
  650. if (m_iPlayerIndex != -1)
  651. {
  652. SetupLocalPlayer(m_aPlayer[m_iPlayerIndex].pid, m_hNewPlayerEvent);
  653. m_aPlayer[m_iPlayerIndex].hEvent = m_hNewPlayerEvent;
  654. if (lpReceiveEvent)
  655. *lpReceiveEvent = m_aPlayer[m_iPlayerIndex].hEvent;
  656. m_hNewPlayerEvent = NULL;
  657. *pPlayerID = (DPID) (0x0000ffff & m_aPlayer[m_iPlayerIndex].pid);
  658. m_iPlayerIndex = -1;
  659. return(DP_OK);
  660. }
  661. }
  662. ResetEvent(m_hNewPlayerEvent);
  663. }
  664. else
  665. {
  666. hr = DPERR_NOMEMORY;
  667. goto abort;
  668. }
  669. }
  670. hr = DPERR_CANTADDPLAYER;
  671. abort:
  672. m_hNewPlayerEvent = NULL;
  673. if (pMsg)
  674. LocalFree((HLOCAL) pMsg);
  675. if (hEvent)
  676. CloseHandle(hEvent);
  677. return(hr);
  678. }
  679. LONG CImpIDP_SP::GetPlayerIndex(DPID playerID)
  680. {
  681. DWORD ii;
  682. DPID pid = 0xffff & ((DPID) playerID);
  683. for (ii = 0; ii < MAX_PLAYERS; ii++)
  684. {
  685. if (m_aPlayer[ii].bValid)
  686. if (m_aPlayer[ii].pid == pid)
  687. return(ii);
  688. }
  689. return(-1);
  690. }
  691. // ----------------------------------------------------------
  692. // DestroyPlayer
  693. // ----------------------------------------------------------
  694. HRESULT CImpIDP_SP::DestroyPlayer( DPID playerID, BOOL bPlayer)
  695. {
  696. LONG iIndex;
  697. DWORD ii, jj;
  698. DPMSG_GETPLAYER dpGet;
  699. SPMSG_GETPLAYER *pMsg;
  700. HANDLE hEvent = NULL;
  701. HRESULT hr = DP_OK;
  702. if ((iIndex = GetPlayerIndex(playerID)) == -1)
  703. return(DPERR_INVALIDPLAYER);
  704. if (m_aPlayer[iIndex].bPlayer != bPlayer)
  705. return(DPERR_INVALIDPLAYER);
  706. if (bPlayer)
  707. {
  708. dpGet.dwType = DPSYS_DELETEPLAYER;
  709. }
  710. else
  711. {
  712. dpGet.dwType = DPSYS_DELETEGROUP;
  713. }
  714. m_dpDesc.dwCurrentPlayers--;
  715. dpGet.dpId = m_aPlayer[iIndex].pid;
  716. if (m_bPlayer0)
  717. {
  718. if (m_aPlayer[iIndex].bLocal)
  719. {
  720. FlushQueue(playerID);
  721. CloseHandle(m_aPlayer[iIndex].hEvent);
  722. }
  723. m_aPlayer[iIndex].bValid = FALSE;
  724. LocalMsg(iIndex, (LPVOID) &dpGet, sizeof(DPMSG_GETPLAYER));
  725. }
  726. pMsg = (SPMSG_GETPLAYER *) malloc(sizeof(SPMSG_GETPLAYER));
  727. if (pMsg)
  728. {
  729. pMsg->dpHdr.usCookie = SPSYS_SYS;
  730. pMsg->dpHdr.to = 0;
  731. pMsg->dpHdr.from = 0;
  732. pMsg->dpHdr.usCount = sizeof(DPMSG_GETPLAYER);
  733. memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGet, sizeof(DPMSG_GETPLAYER));
  734. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  735. }
  736. for (ii = 0; ii < MAX_PLAYERS; ii++)
  737. {
  738. if ( m_aPlayer[ii].bValid == TRUE
  739. && m_aPlayer[ii].bPlayer == FALSE
  740. && m_aPlayer[ii].aGroup)
  741. {
  742. for (jj = 0; jj < MAX_PLAYERS; jj++)
  743. {
  744. if (m_aPlayer[ii].aGroup[jj] == playerID)
  745. {
  746. m_aPlayer[ii].aGroup[jj] = 0;
  747. break;
  748. }
  749. }
  750. }
  751. }
  752. return(DP_OK);
  753. }
  754. // ----------------------------------------------------------
  755. // Close - close the connection
  756. // ----------------------------------------------------------
  757. HRESULT CImpIDP_SP::Close( DWORD dwFlag)
  758. {
  759. DWORD ii;
  760. TSHELL_INFO(TEXT("Close Processing."));
  761. for (ii = 0; ii < MAX_PLAYERS; ii++)
  762. {
  763. if (m_aPlayer[ii].bValid)
  764. {
  765. m_aPlayer[ii].bValid = FALSE;
  766. if (m_aPlayer[ii].bLocal && m_aPlayer[ii].bPlayer)
  767. {
  768. FlushQueue(m_aPlayer[ii].pid);
  769. CloseHandle(m_aPlayer[ii].hEvent);
  770. }
  771. }
  772. }
  773. g_bIgnoreReads = FALSE;
  774. m_bConnected = FALSE;
  775. m_bPlayer0 = FALSE;
  776. PostHangup();
  777. return(DP_OK);
  778. }
  779. // ----------------------------------------------------------
  780. // GetName -
  781. // ----------------------------------------------------------
  782. HRESULT CImpIDP_SP::GetPlayerName(
  783. DPID dpID,
  784. LPSTR lpNickName, // buffer to hold name
  785. LPDWORD pdwNickNameLength, // length of name buffer
  786. LPSTR lpFullName,
  787. LPDWORD pdwFullNameLength
  788. )
  789. {
  790. LONG iIndex;
  791. HRESULT hr = DP_OK;
  792. DPID pid = (DPID) dpID;
  793. if ((iIndex = GetPlayerIndex(dpID)) != -1)
  794. {
  795. lstrcpy( lpNickName, m_aPlayer[iIndex].chNickName);
  796. lstrcpy( lpFullName, m_aPlayer[iIndex].chFullName);
  797. *pdwNickNameLength = lstrlen(lpNickName) + 1;
  798. *pdwFullNameLength = lstrlen(lpFullName) + 1;
  799. return(DP_OK);
  800. }
  801. else
  802. {
  803. return(DPERR_INVALIDPID);
  804. }
  805. }
  806. HRESULT CImpIDP_SP::EnumGroupPlayers(
  807. DPID dwGroupPid,
  808. LPDPENUMPLAYERSCALLBACK EnumCallback,
  809. LPVOID pContext,
  810. DWORD dwFlags)
  811. {
  812. DWORD ii;
  813. HRESULT hr = DP_OK;
  814. LONG iIndexG;
  815. LONG iIndexP;
  816. DPID pid;
  817. iIndexG = GetPlayerIndex(dwGroupPid);
  818. if (iIndexG == -1)
  819. return(DPERR_INVALIDPID);
  820. if (m_aPlayer[iIndexG].bPlayer)
  821. return(DPERR_INVALIDPID);
  822. for (ii = 0; ii < MAX_PLAYERS; ii++)
  823. {
  824. if ((pid = m_aPlayer[iIndexG].aGroup[ii]) != 0)
  825. {
  826. iIndexP = GetPlayerIndex(pid);
  827. if (iIndexP != -1)
  828. {
  829. (EnumCallback)((DPID) m_aPlayer[iIndexP].pid,
  830. m_aPlayer[iIndexP].chNickName,
  831. m_aPlayer[iIndexP].chFullName,
  832. ((m_aPlayer[iIndexP].bLocal ) ? DPENUMPLAYERS_LOCAL : DPENUMPLAYERS_REMOTE)
  833. | ((!m_aPlayer[iIndexP].bPlayer) ? DPENUMPLAYERS_GROUP : 0),
  834. pContext);
  835. }
  836. else
  837. {
  838. m_aPlayer[iIndexG].aGroup[ii] = 0;
  839. }
  840. }
  841. }
  842. return(DP_OK);
  843. }
  844. // ----------------------------------------------------------
  845. // EnumPlayers - return info on peer connections.
  846. // ----------------------------------------------------------
  847. HRESULT CImpIDP_SP::EnumPlayers(
  848. DWORD dwSessionId,
  849. LPDPENUMPLAYERSCALLBACK EnumCallback,
  850. LPVOID pContext,
  851. DWORD dwFlags)
  852. {
  853. DWORD ii;
  854. HRESULT hr = DP_OK;
  855. if (dwFlags & DPENUMPLAYERS_PREVIOUS)
  856. {
  857. return(DPERR_UNSUPPORTED);
  858. }
  859. for (ii = 0; ii < MAX_PLAYERS; ii++)
  860. if ( m_aPlayer[ii].bValid
  861. && ( (m_aPlayer[ii].bPlayer == FALSE && (dwFlags & DPENUMPLAYERS_GROUP))
  862. || (m_aPlayer[ii].bPlayer == TRUE && !(dwFlags & DPENUMPLAYERS_NOPLAYERS))))
  863. {
  864. if((EnumCallback)((DPID) m_aPlayer[ii].pid,
  865. m_aPlayer[ii].chNickName,
  866. m_aPlayer[ii].chFullName,
  867. ((m_aPlayer[ii].bLocal ) ? DPENUMPLAYERS_LOCAL : DPENUMPLAYERS_REMOTE)
  868. | ((!m_aPlayer[ii].bPlayer) ? DPENUMPLAYERS_GROUP : 0),
  869. pContext) == FALSE)
  870. {
  871. break;
  872. }
  873. }
  874. return(DP_OK);
  875. }
  876. HRESULT CImpIDP_SP::EnumSessions(
  877. LPDPSESSIONDESC lpSDesc,
  878. DWORD dwTimeout,
  879. LPDPENUMSESSIONSCALLBACK EnumCallback,
  880. LPVOID lpvContext,
  881. DWORD dwFlags)
  882. {
  883. DPSESSIONDESC dpSDesc;
  884. memcpy( &dpSDesc.guidSession, &(lpSDesc->guidSession), sizeof(GUID));
  885. dpSDesc.dwSession = 0;
  886. dpSDesc.dwMaxPlayers = MAX_PLAYERS;
  887. dpSDesc.dwCurrentPlayers = 0;
  888. dpSDesc.dwFlags = 0;
  889. dpSDesc.dwSize = sizeof(DPSESSIONDESC);
  890. LoadString(hInst, IDS_DIALNEW, dpSDesc.szSessionName, sizeof(dpSDesc.szSessionName));
  891. EnumCallback( &dpSDesc, lpvContext, NULL, 0);
  892. if (m_dwSessionPrev && dwFlags & DPENUMSESSIONS_PREVIOUS)
  893. {
  894. DWORD ii;
  895. DWORD dw;
  896. for (ii = 0; ii < m_dwSessionPrev; ii++)
  897. {
  898. dpSDesc.dwSession = ii + 1;
  899. dw = *((DWORD *)(m_ppSessionArray[ii]));
  900. lstrcpyn( dpSDesc.szSessionName,
  901. ((m_ppSessionArray[ii]) + sizeof(DWORD) + dw), DPLONGNAMELEN);
  902. dpSDesc.szSessionName[DPLONGNAMELEN-1] = 0x00;
  903. EnumCallback( &dpSDesc, lpvContext, NULL, 0);
  904. }
  905. }
  906. return(DP_OK);
  907. }
  908. VOID CImpIDP_SP::ISend(
  909. LONG iFrom,
  910. LONG iTo,
  911. DWORD dwFlags,
  912. LPVOID lpvBuffer,
  913. DWORD dwBuffSize)
  914. {
  915. MSG_BUILDER *pMsg;
  916. DWORD ii;
  917. LONG iIndexT;
  918. if (m_aPlayer[iTo].bPlayer == FALSE)
  919. {
  920. for (ii = 0; ii < MAX_PLAYERS; ii++)
  921. {
  922. if (m_aPlayer[iTo].aGroup[ii])
  923. if ((iIndexT = GetPlayerIndex(m_aPlayer[iTo].aGroup[ii])) != -1)
  924. ISend(iFrom, iIndexT, dwFlags, lpvBuffer, dwBuffSize);
  925. }
  926. }
  927. else
  928. {
  929. if (m_aPlayer[iTo].bLocal)
  930. {
  931. AddMessage(lpvBuffer,
  932. dwBuffSize,
  933. m_aPlayer[iTo].pid,
  934. m_aPlayer[iFrom].pid,
  935. dwFlags & DPSEND_HIGHPRIORITY);
  936. }
  937. else
  938. {
  939. LPVOID lpv = malloc(sizeof(DPHDR) + dwBuffSize);
  940. if (!lpv)
  941. return;
  942. // TSHELL_INFO(TEXT("Sending Remote Message."));
  943. pMsg = (MSG_BUILDER *) lpv;
  944. pMsg->dpHdr.usCookie = (dwFlags & DPSEND_HIGHPRIORITY) ? SPSYS_HIGH : SPSYS_USER;
  945. pMsg->dpHdr.to = (BYTE) m_aPlayer[iTo].pid;
  946. pMsg->dpHdr.from = (BYTE) m_aPlayer[iFrom].pid;
  947. pMsg->dpHdr.usCount = (USHORT) dwBuffSize;
  948. memcpy( pMsg->chMsgCompose, lpvBuffer, dwBuffSize);
  949. WriteCommString( (LPVOID) pMsg, sizeof(DPHDR) + dwBuffSize);
  950. lpv = NULL;
  951. }
  952. }
  953. }
  954. // ----------------------------------------------------------
  955. // Send - transmit data over socket.
  956. // ----------------------------------------------------------
  957. HRESULT CImpIDP_SP::Send(
  958. DPID from,
  959. DPID to,
  960. DWORD dwFlags,
  961. LPVOID lpvBuffer,
  962. DWORD dwBuffSize)
  963. {
  964. DWORD ii;
  965. LONG iFrom;
  966. BOOL bSent = FALSE;
  967. if (m_dwPendingWrites > m_dpcaps.dwMaxQueueSize)
  968. {
  969. return(DPERR_BUSY);
  970. }
  971. if (dwBuffSize > MAX_MSG)
  972. return(DPERR_INVALIDPARAMS);
  973. if (from == 0)
  974. {
  975. return(DPERR_INVALIDPID);
  976. }
  977. else
  978. {
  979. iFrom = GetPlayerIndex(from);
  980. // DBG_INFO((DBGARG, TEXT("Send From Pid %d Player Index %d"), from, iFrom));
  981. if (iFrom == -1)
  982. for (ii = 0; ii < MAX_PLAYERS; ii++)
  983. {
  984. DBG_INFO((DBGARG, TEXT("Index %d Valid %d Pid %d Local %d"),
  985. ii,
  986. m_aPlayer[ii].bValid,
  987. m_aPlayer[ii].pid,
  988. m_aPlayer[ii].bLocal));
  989. }
  990. if (iFrom == -1 || ! m_aPlayer[iFrom].bLocal)
  991. return(DPERR_INVALIDPID);
  992. }
  993. for (ii = 0; ii < MAX_PLAYERS; ii++)
  994. if (m_aPlayer[ii].bValid && m_aPlayer[ii].pid != from)
  995. {
  996. if ( (to == 0 && m_aPlayer[ii].bPlayer == TRUE)
  997. || m_aPlayer[ii].pid == to)
  998. {
  999. ISend(iFrom, ii, dwFlags, lpvBuffer, dwBuffSize);
  1000. bSent = TRUE;
  1001. }
  1002. }
  1003. return(bSent ? m_dwPendingWrites : DPERR_INVALIDPID);
  1004. }
  1005. // ----------------------------------------------------------
  1006. // Receive - receive message
  1007. // ----------------------------------------------------------
  1008. HRESULT CImpIDP_SP::Receive(
  1009. LPDPID pidfrom,
  1010. LPDPID pidto,
  1011. DWORD dwFlags,
  1012. LPVOID lpvBuffer,
  1013. LPDWORD lpdwSize)
  1014. {
  1015. HRESULT hr;
  1016. LONG iIndex;
  1017. BOOL bb;
  1018. bb = TRUE;
  1019. if (dwFlags & DPRECEIVE_TOPLAYER)
  1020. {
  1021. iIndex = GetPlayerIndex(*pidto);
  1022. if (iIndex == -1 || m_aPlayer[iIndex].bLocal == FALSE)
  1023. bb = FALSE;
  1024. }
  1025. if ((dwFlags & DPRECEIVE_FROMPLAYER) && *pidfrom != 0)
  1026. {
  1027. iIndex = GetPlayerIndex(*pidfrom);
  1028. if (iIndex == -1 || m_aPlayer[iIndex].bLocal == FALSE)
  1029. bb = FALSE;
  1030. }
  1031. if (bb == FALSE)
  1032. {
  1033. return(DPERR_INVALIDPID);
  1034. }
  1035. hr = GetQMessage(lpvBuffer, lpdwSize, pidto, pidfrom, dwFlags,
  1036. dwFlags & DPRECEIVE_PEEK);
  1037. return(hr);
  1038. }
  1039. HRESULT CImpIDP_SP::SetPlayerName(
  1040. DPID pid,
  1041. LPSTR lpFriendlyName,
  1042. LPSTR lpFormalName,
  1043. BOOL bPlayer)
  1044. {
  1045. SPMSG_ADDPLAYER *pMsg;
  1046. //
  1047. // Send DPSYS_SETPLAYER to nameserver.
  1048. //
  1049. LONG iIndex = GetPlayerIndex(pid);
  1050. if (iIndex == -1)
  1051. return(DPERR_INVALIDPLAYER);
  1052. if (m_aPlayer[iIndex].bPlayer != bPlayer)
  1053. return(DPERR_INVALIDPLAYER);
  1054. lstrcpyn( m_aPlayer[iIndex].chNickName, lpFriendlyName, DPSHORTNAMELEN);
  1055. lstrcpyn( m_aPlayer[iIndex].chFullName, lpFormalName , DPLONGNAMELEN);
  1056. pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
  1057. if (!pMsg)
  1058. {
  1059. return(DPERR_NOMEMORY);
  1060. }
  1061. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1062. pMsg->dpHdr.to = 0;
  1063. pMsg->dpHdr.from = 0;
  1064. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  1065. pMsg->sMsg.dwType = DPSYS_SETPLAYER;
  1066. pMsg->sMsg.dwPlayerType = bPlayer;
  1067. pMsg->sMsg.dpId = m_aPlayer[iIndex].pid;
  1068. lstrcpy( pMsg->sMsg.szShortName, lpFriendlyName);
  1069. lstrcpy( pMsg->sMsg.szLongName, lpFormalName);
  1070. WriteCommString( pMsg, sizeof(SPMSG_ADDPLAYER));
  1071. return(DP_OK);
  1072. }
  1073. HRESULT CImpIDP_SP::SaveSession(LPVOID lpv, LPDWORD lpdw)
  1074. {
  1075. DWORD dwLen;
  1076. if (!m_bConnected)
  1077. return(DPERR_NOCONNECTION);
  1078. if (m_bPlayer0)
  1079. return(DPERR_UNSUPPORTED);
  1080. if (m_lpDialable[0] == 0x00)
  1081. return(DPERR_GENERIC);
  1082. dwLen = 1 + lstrlen(m_lpDialable);
  1083. if (*lpdw < dwLen)
  1084. {
  1085. *lpdw = dwLen;
  1086. TSHELL_INFO(TEXT("SaveSession buffer too small."));
  1087. return(DPERR_BUFFERTOOSMALL);
  1088. }
  1089. if (lpv)
  1090. {
  1091. lstrcpy( (char *) lpv, m_lpDialable);
  1092. *lpdw = dwLen;
  1093. }
  1094. return(DP_OK);
  1095. }
  1096. HRESULT CImpIDP_SP::SetPrevSession(LPSTR lpName, LPVOID lpv, DWORD dw)
  1097. {
  1098. //
  1099. //
  1100. //
  1101. DWORD dwLen;
  1102. // TSHELL_INFO(TEXT("SetPrevSession"));
  1103. if (m_dwSessionAlloc == m_dwSessionPrev)
  1104. {
  1105. char **ppTmp;
  1106. m_dwSessionAlloc += 16;
  1107. ppTmp = (char **) malloc(sizeof(char *) * m_dwSessionAlloc);
  1108. if (ppTmp)
  1109. {
  1110. if (m_ppSessionArray)
  1111. {
  1112. memcpy( ppTmp, m_ppSessionArray, m_dwSessionPrev);
  1113. free(m_ppSessionArray);
  1114. }
  1115. }
  1116. else
  1117. {
  1118. m_dwSessionAlloc -= 16;
  1119. return(DPERR_NOMEMORY);
  1120. }
  1121. m_ppSessionArray = ppTmp;
  1122. }
  1123. dwLen = lstrlen(lpName) + 1;
  1124. m_ppSessionArray[m_dwSessionPrev] = (char *) malloc(dwLen + dw + sizeof(dw));
  1125. if (m_ppSessionArray[m_dwSessionPrev])
  1126. {
  1127. // TSHELL_INFO(TEXT("Fill in structure"));
  1128. *((DWORD *)(m_ppSessionArray[m_dwSessionPrev])) = dw;
  1129. memcpy(((m_ppSessionArray[m_dwSessionPrev]) + sizeof(dw)), lpv, dw);
  1130. lstrcpy(((m_ppSessionArray[m_dwSessionPrev]) + sizeof(dw) + dw), lpName);
  1131. m_dwSessionPrev++;
  1132. return(DP_OK);
  1133. }
  1134. else
  1135. {
  1136. return(DPERR_NOMEMORY);
  1137. }
  1138. return(DPERR_UNSUPPORTED);
  1139. }
  1140. HRESULT CImpIDP_SP::SetPrevPlayer(LPSTR lpName, LPVOID lpv, DWORD dw)
  1141. {
  1142. //
  1143. //
  1144. // This doesn't make sense for a serial point to point SP.
  1145. //
  1146. TSHELL_INFO( TEXT("not currently supported") );
  1147. return(DPERR_UNSUPPORTED);
  1148. }
  1149. HRESULT CImpIDP_SP::EnableNewPlayers(BOOL bEnable)
  1150. {
  1151. //
  1152. // Implementation not set, and won't follow this calling convention.
  1153. // ignore for now.
  1154. //
  1155. SPMSG_ENABLEPLAYER *pMsg;
  1156. pMsg = (SPMSG_ENABLEPLAYER *) malloc(sizeof(SPMSG_ENABLEPLAYER));
  1157. if (pMsg)
  1158. {
  1159. m_bEnablePlayerAdd = bEnable;
  1160. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1161. pMsg->dpHdr.to = 0;
  1162. pMsg->dpHdr.from = 0;
  1163. pMsg->dpHdr.usCount = sizeof(DPMSG_ENABLEPLAYER);
  1164. pMsg->sMsg.dwType = DPSYS_ENABLEPLAYER;
  1165. pMsg->sMsg.bEnable = bEnable;
  1166. WriteCommString( pMsg, sizeof(SPMSG_ENABLEPLAYER));
  1167. return(DP_OK);
  1168. }
  1169. else
  1170. return(DPERR_NOMEMORY);
  1171. }
  1172. HRESULT CImpIDP_SP::GetPlayerCaps(
  1173. DPID pid,
  1174. LPDPCAPS lpDPCaps)
  1175. {
  1176. LONG iIndex = GetPlayerIndex(pid);
  1177. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
  1178. return(DPERR_INVALIDPID);
  1179. m_dpcaps.dwHundredBaud = g_dwRate / 100;
  1180. *lpDPCaps = m_dpcaps;
  1181. if (m_aPlayer[iIndex].bLocal)
  1182. lpDPCaps->dwLatency = 1;
  1183. return(DP_OK);
  1184. }
  1185. HRESULT CImpIDP_SP::GetMessageCount(DPID pid, LPDWORD lpdw )
  1186. {
  1187. //
  1188. // Return count for this pid, if it is a local player we have
  1189. // been tracking with Interlock calls.
  1190. //
  1191. LONG iIndex = GetPlayerIndex((DPID) pid);
  1192. if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
  1193. return(DPERR_INVALIDPLAYER);
  1194. if (m_aPlayer[iIndex].bLocal == FALSE)
  1195. return(DPERR_INVALIDPLAYER);
  1196. *lpdw = GetPlayerCount((DPID) pid);
  1197. return(DP_OK);
  1198. }
  1199. HRESULT CImpIDP_SP::AddPlayerToGroup(
  1200. DPID pidGroup,
  1201. DPID pidPlayer)
  1202. {
  1203. DPMSG_GROUPADD dpGAdd;
  1204. LONG iIndexG;
  1205. LONG iIndexP;
  1206. DWORD ii;
  1207. SPMSG_GROUPADD *pMsg;
  1208. iIndexG = GetPlayerIndex(pidGroup);
  1209. iIndexP = GetPlayerIndex(pidPlayer);
  1210. if (iIndexG == -1 || m_aPlayer[iIndexG].bPlayer == TRUE)
  1211. return(DPERR_INVALIDPID);
  1212. if (iIndexP == -1 || m_aPlayer[iIndexP].bPlayer == FALSE)
  1213. return(DPERR_INVALIDPID);
  1214. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1215. {
  1216. if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
  1217. {
  1218. return(DPERR_INVALIDPID);
  1219. }
  1220. }
  1221. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1222. {
  1223. if (m_aPlayer[iIndexG].aGroup[ii] == 0)
  1224. {
  1225. dpGAdd.dwType = DPSYS_ADDPLAYERTOGROUP;
  1226. dpGAdd.dpIdGroup = m_aPlayer[iIndexG].pid;
  1227. dpGAdd.dpIdPlayer = m_aPlayer[iIndexP].pid;
  1228. LocalMsg(iIndexG, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1229. m_aPlayer[iIndexG].aGroup[ii] = m_aPlayer[iIndexP].pid;
  1230. pMsg = (SPMSG_GROUPADD *) malloc(sizeof(SPMSG_GROUPADD));
  1231. if (pMsg)
  1232. {
  1233. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1234. pMsg->dpHdr.to = 0;
  1235. pMsg->dpHdr.from = 0;
  1236. pMsg->dpHdr.usCount = sizeof(DPMSG_GROUPADD);
  1237. memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1238. WriteCommString( pMsg, sizeof(SPMSG_GROUPADD));
  1239. return(DP_OK);
  1240. }
  1241. else
  1242. return(DPERR_NOMEMORY);
  1243. }
  1244. }
  1245. return(DPERR_GENERIC);
  1246. }
  1247. HRESULT CImpIDP_SP::DeletePlayerFromGroup(
  1248. DPID pidGroup,
  1249. DPID pidPlayer)
  1250. {
  1251. DPMSG_GROUPADD dpGAdd;
  1252. LONG iIndexG;
  1253. LONG iIndexP;
  1254. DWORD ii;
  1255. SPMSG_GROUPADD *pMsg;
  1256. iIndexG = GetPlayerIndex(pidGroup);
  1257. iIndexP = GetPlayerIndex(pidPlayer);
  1258. if (iIndexG == -1 || m_aPlayer[iIndexG].bPlayer == TRUE)
  1259. return(DPERR_INVALIDPID);
  1260. if (iIndexP == -1 || m_aPlayer[iIndexP].bPlayer == FALSE)
  1261. return(DPERR_INVALIDPID);
  1262. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1263. {
  1264. if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
  1265. {
  1266. dpGAdd.dwType = DPSYS_DELETEPLAYERFROMGRP;
  1267. dpGAdd.dpIdGroup = m_aPlayer[iIndexG].pid;
  1268. dpGAdd.dpIdPlayer = m_aPlayer[iIndexP].pid;
  1269. LocalMsg(iIndexG, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1270. m_aPlayer[iIndexG].aGroup[ii] = 0;
  1271. pMsg = (SPMSG_GROUPADD *) malloc(sizeof(SPMSG_GROUPADD));
  1272. if (pMsg)
  1273. {
  1274. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1275. pMsg->dpHdr.to = 0;
  1276. pMsg->dpHdr.from = 0;
  1277. pMsg->dpHdr.usCount = sizeof(DPMSG_GROUPADD);
  1278. memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
  1279. WriteCommString( pMsg, sizeof(SPMSG_GROUPADD));
  1280. return(DP_OK);
  1281. }
  1282. else
  1283. return(DPERR_NOMEMORY);
  1284. }
  1285. }
  1286. return(DPERR_INVALIDPID);
  1287. }
  1288. VOID CImpIDP_SP::HandleMessage(LPVOID lpv, DWORD dwSize)
  1289. {
  1290. DPHDR *pHdr;
  1291. BOOL bHigh = FALSE;
  1292. DPID pidTo, pidFrom;
  1293. DWORD ii;
  1294. SPMSG_ADDPLAYER *pAddPlayer;
  1295. LONG iIndex;
  1296. pHdr = (DPHDR *) lpv;
  1297. // TSHELL_INFO(TEXT("HandleMessage entered."));
  1298. switch(pHdr->usCookie)
  1299. {
  1300. default:
  1301. TSHELL_INFO(TEXT("Unknown message value"));
  1302. break;
  1303. case SPSYS_CONNECT:
  1304. SPMSG_CONNECT *pConnect;
  1305. pConnect = (SPMSG_CONNECT *) lpv;
  1306. if ( pConnect->dpHdr.usCount == sizeof(SPMSG_CONNECT) - sizeof(DPHDR)
  1307. && pConnect->usVerMajor == DPVERSION_MAJOR
  1308. && pConnect->usVerMinor == DPVERSION_MINOR
  1309. && pConnect->dwConnect1 == DPSYS_KYRA
  1310. && pConnect->dwConnect2 == DPSYS_HALL)
  1311. {
  1312. HandleConnect();
  1313. }
  1314. return;
  1315. case SPSYS_HIGH:
  1316. bHigh = TRUE;
  1317. //
  1318. // Fall Through!
  1319. //
  1320. case SPSYS_USER:
  1321. pidTo = 0x00ff & ((DPID) pHdr->to);
  1322. pidFrom = 0x00ff & ((DPID) pHdr->from);
  1323. dwSize = (DWORD) ((DPID) pHdr->usCount);
  1324. AddMessage((LPVOID) (((LPBYTE) lpv) + sizeof(DPHDR)), dwSize,
  1325. pidTo, pidFrom, bHigh);
  1326. if ( pidFrom != 0
  1327. && ((iIndex = GetPlayerIndex(pidFrom)) == -1))
  1328. {
  1329. SPMSG_GETPLAYER *pMsg;
  1330. pMsg = (SPMSG_GETPLAYER *) malloc(sizeof(SPMSG_GETPLAYER));
  1331. if (pMsg)
  1332. {
  1333. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1334. pMsg->dpHdr.to = 0;
  1335. pMsg->dpHdr.from = 0;
  1336. pMsg->dpHdr.usCount = sizeof(DPMSG_GETPLAYER);
  1337. pMsg->sMsg.dwType = DPSYS_GETPLAYER;
  1338. pMsg->sMsg.dpId = pidFrom;
  1339. WriteCommString((LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  1340. }
  1341. }
  1342. break;
  1343. case SPSYS_SYS:
  1344. TSHELL_INFO(TEXT("HandleMessage System Message."));
  1345. switch(((SPMSG_GENERIC *)lpv)->sMsg.dwType)
  1346. {
  1347. default:
  1348. DBG_INFO((DBGARG, TEXT("Unknown Type %x"), ((SPMSG_GENERIC *)lpv)->sMsg.dwType));
  1349. break;
  1350. case DPSYS_ENABLEPLAYER:
  1351. {
  1352. SPMSG_ENABLEPLAYER *pMsg;
  1353. pMsg = (SPMSG_ENABLEPLAYER *) lpv;
  1354. if (pMsg->dpHdr.usCount == sizeof(DPMSG_ENABLEPLAYER))
  1355. {
  1356. m_bEnablePlayerAdd = pMsg->sMsg.bEnable;
  1357. }
  1358. }
  1359. break;
  1360. case DPSYS_SETGROUPPLAYER:
  1361. {
  1362. SPMSG_SETGROUPPLAYERS16 *pMsgG;
  1363. LONG iIndexG;
  1364. DWORD ii, jj;
  1365. DPID pid;
  1366. pMsgG = (SPMSG_SETGROUPPLAYERS16 *) lpv;
  1367. if (pMsgG->dpHdr.usCount == (sizeof(SPMSG_SETGROUPPLAYERS16) - sizeof(DPHDR)))
  1368. {
  1369. iIndexG = GetPlayerIndex((DPID) (0x000000ff & pMsgG->Group));
  1370. if (iIndexG == -1)
  1371. {
  1372. TSHELL_INFO(TEXT("Invalid SetGroupMembers message."));
  1373. }
  1374. else
  1375. {
  1376. for (ii = 0, jj = 0; ii < 16; ii++)
  1377. {
  1378. if (pMsgG->bytePlayers[ii] != 0)
  1379. {
  1380. pid = (DPID) (0x000000ff & pMsgG->bytePlayers[ii]);
  1381. if (GetPlayerIndex(pid) != -1)
  1382. {
  1383. m_aPlayer[iIndexG].aGroup[jj++] = pid;
  1384. }
  1385. }
  1386. }
  1387. }
  1388. }
  1389. }
  1390. break;
  1391. case DPSYS_DELETEPLAYERFROMGRP:
  1392. case DPSYS_ADDPLAYERTOGROUP:
  1393. {
  1394. SPMSG_GROUPADD *pMsg;
  1395. LONG iIndexG;
  1396. LONG iIndexP;
  1397. pMsg = (SPMSG_GROUPADD *) lpv;
  1398. if (pMsg->dpHdr.usCount == sizeof(DPMSG_GROUPADD))
  1399. {
  1400. iIndexG = GetPlayerIndex(pMsg->sMsg.dpIdGroup);
  1401. iIndexP = GetPlayerIndex(pMsg->sMsg.dpIdPlayer);
  1402. if ( iIndexG == -1
  1403. || m_aPlayer[iIndexG].bPlayer == TRUE
  1404. || iIndexP == -1
  1405. || m_aPlayer[iIndexP].bPlayer == FALSE)
  1406. {
  1407. TSHELL_INFO(TEXT("Invalid GroupAdd message."));
  1408. }
  1409. else
  1410. {
  1411. if (pMsg->sMsg.dwType == DPSYS_ADDPLAYERTOGROUP)
  1412. {
  1413. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1414. if (m_aPlayer[iIndexG].aGroup[ii] == 0)
  1415. {
  1416. m_aPlayer[iIndexG].aGroup[ii] = m_aPlayer[iIndexP].pid;
  1417. LocalMsg(iIndexG, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GROUPADD));
  1418. break;
  1419. }
  1420. }
  1421. else
  1422. {
  1423. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1424. if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
  1425. {
  1426. m_aPlayer[iIndexG].aGroup[ii] = 0;
  1427. LocalMsg(iIndexG, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GROUPADD));
  1428. }
  1429. }
  1430. }
  1431. }
  1432. else
  1433. {
  1434. TSHELL_INFO(TEXT("Invalid size on system message"));
  1435. }
  1436. }
  1437. break;
  1438. case DPSYS_SENDDESC:
  1439. {
  1440. SPMSG_SENDDESC *pMsg;
  1441. pMsg = (SPMSG_SENDDESC *) lpv;
  1442. if (pMsg->dpHdr.usCount == SIZE_SENDDESC)
  1443. {
  1444. memcpy( (LPVOID) &m_dpDesc, (LPVOID) &pMsg->dpDesc, sizeof(m_dpDesc));
  1445. DBG_INFO((DBGARG, TEXT("New Description. Current Players %d, Max %d"),
  1446. m_dpDesc.dwCurrentPlayers, m_dpDesc.dwMaxPlayers));
  1447. }
  1448. else
  1449. {
  1450. TSHELL_INFO(TEXT("Bad SendDesc message."));
  1451. }
  1452. }
  1453. break;
  1454. case DPSYS_PING:
  1455. {
  1456. SPMSG_PING *pMsg;
  1457. pMsg = (SPMSG_PING *) lpv;
  1458. if (pMsg->dpHdr.usCount == SIZE_PING)
  1459. {
  1460. if (pMsg->dwTicks == m_dwPingSent)
  1461. {
  1462. m_dpcaps.dwLatency = (GetTickCount() - m_dwPingSent) /2;
  1463. m_dwPingSent = 0;
  1464. // TSHELL_INFO(TEXT("Latency Accepted from our Ping."));
  1465. }
  1466. else
  1467. {
  1468. SPMSG_PING *pMsg2;
  1469. pMsg2 = (SPMSG_PING *) malloc(sizeof(SPMSG_PING));
  1470. if (pMsg2)
  1471. {
  1472. memcpy( (LPVOID) pMsg2, (LPVOID) pMsg, sizeof(SPMSG_PING));
  1473. WriteCommString(pMsg2, sizeof(SPMSG_PING));
  1474. // TSHELL_INFO(TEXT("Return Ping."));
  1475. }
  1476. }
  1477. TSHELL_INFO(TEXT("Ping Recieved."));
  1478. }
  1479. }
  1480. break;
  1481. case DPSYS_SETPLAYER:
  1482. {
  1483. pAddPlayer = (SPMSG_ADDPLAYER *) lpv;
  1484. TSHELL_INFO(TEXT("Received SETPLAYER message"));
  1485. if (pAddPlayer->dpHdr.usCount == SIZE_ADDPLAYER)
  1486. {
  1487. iIndex = GetPlayerIndex(pAddPlayer->sMsg.dpId);
  1488. if (iIndex != -1)
  1489. {
  1490. if (m_aPlayer[iIndex].bPlayer == (BOOL) pAddPlayer->sMsg.dwPlayerType)
  1491. {
  1492. lstrcpyn( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName, DPSHORTNAMELEN);
  1493. lstrcpyn( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName , DPLONGNAMELEN);
  1494. }
  1495. TSHELL_INFO(TEXT("Name change through SETPLAYER"));
  1496. }
  1497. else if ( !m_bPlayer0
  1498. && ((iIndex = FindInvalidIndex()) != -1))
  1499. {
  1500. lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
  1501. lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
  1502. m_aPlayer[iIndex].bValid = TRUE;
  1503. m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
  1504. m_aPlayer[iIndex].bLocal = FALSE;
  1505. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1506. m_aPlayer[iIndex].aGroup[ii] = 0;
  1507. m_aPlayer[iIndex].pid = pAddPlayer->sMsg.dpId;
  1508. TSHELL_INFO(TEXT("Remote player updated with SETPLAYER."));
  1509. }
  1510. }
  1511. }
  1512. break;
  1513. case DPSYS_ADDPLAYER:
  1514. {
  1515. pAddPlayer = (SPMSG_ADDPLAYER *) lpv;
  1516. if (pAddPlayer->dpHdr.usCount == SIZE_ADDPLAYER)
  1517. {
  1518. if (m_bEnablePlayerAdd == FALSE && pAddPlayer->sMsg.dwPlayerType == TRUE)
  1519. break;
  1520. if (m_bPlayer0)
  1521. {
  1522. TSHELL_INFO(TEXT("Begin AddPlayer Processing Player 0."));
  1523. if ( m_dpDesc.dwMaxPlayers >= m_dpDesc.dwCurrentPlayers
  1524. && pAddPlayer->sMsg.dpId == 0
  1525. && ((iIndex = FindInvalidIndex()) != -1)
  1526. && (m_dwNextPlayer < MAXIMUM_PLAYER_ID))
  1527. {
  1528. SPMSG_ADDPLAYER *pReplyMsg;
  1529. m_dpDesc.dwCurrentPlayers++;
  1530. m_aPlayer[iIndex].pid = (DPID) m_dwNextPlayer++;
  1531. lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
  1532. lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
  1533. m_aPlayer[iIndex].bValid = TRUE;
  1534. m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
  1535. m_aPlayer[iIndex].bLocal = FALSE;
  1536. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1537. m_aPlayer[iIndex].aGroup[ii] = 0;
  1538. pAddPlayer->sMsg.dpId = m_aPlayer[iIndex].pid;
  1539. pReplyMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
  1540. if (pReplyMsg)
  1541. {
  1542. TSHELL_INFO(TEXT("Replying to AddPlayer message."));
  1543. memcpy((LPVOID) pReplyMsg, (LPVOID) pAddPlayer,
  1544. sizeof(SPMSG_ADDPLAYER));
  1545. WriteCommString( (LPVOID) pReplyMsg, sizeof(SPMSG_ADDPLAYER));
  1546. }
  1547. LocalMsg(iIndex, &pAddPlayer->sMsg, sizeof(DPMSG_ADDPLAYER));
  1548. }
  1549. else
  1550. {
  1551. TSHELL_INFO(TEXT("Ignoring message, it will timeout."));
  1552. }
  1553. }
  1554. else
  1555. {
  1556. TSHELL_INFO(TEXT("Begin AddPlayer Processing Remote."));
  1557. iIndex = GetPlayerIndex(pAddPlayer->sMsg.dpId);
  1558. if (iIndex == -1 && (iIndex = FindInvalidIndex()) != -1)
  1559. {
  1560. lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
  1561. lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
  1562. m_aPlayer[iIndex].bValid = TRUE;
  1563. m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
  1564. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1565. m_aPlayer[iIndex].aGroup[ii] = 0;
  1566. m_aPlayer[iIndex].pid = pAddPlayer->sMsg.dpId;
  1567. LocalMsg(iIndex, &pAddPlayer->sMsg, sizeof(DPMSG_ADDPLAYER));
  1568. if (m_hNewPlayerEvent)
  1569. {
  1570. m_aPlayer[iIndex].bLocal = TRUE;
  1571. m_iPlayerIndex = iIndex;
  1572. SetEvent(m_hNewPlayerEvent);
  1573. }
  1574. else
  1575. m_aPlayer[iIndex].bLocal = FALSE;
  1576. }
  1577. }
  1578. }
  1579. else
  1580. {
  1581. TSHELL_INFO(TEXT("Invalid size on system message ADDPLAYER"));
  1582. }
  1583. }
  1584. break;
  1585. case DPSYS_DELETEGROUP:
  1586. case DPSYS_DELETEPLAYER:
  1587. {
  1588. SPMSG_GETPLAYER *pMsg;
  1589. SPMSG_GETPLAYER *pMsg2;
  1590. pMsg = (SPMSG_GETPLAYER *) lpv;
  1591. TSHELL_INFO(TEXT("Got Delete"));
  1592. if (pMsg->dpHdr.usCount == SIZE_GETPLAYER)
  1593. {
  1594. if ((iIndex = GetPlayerIndex(pMsg->sMsg.dpId)) != -1)
  1595. {
  1596. if (m_bPlayer0)
  1597. {
  1598. pMsg2 = (SPMSG_GETPLAYER *) malloc(sizeof(SPMSG_GETPLAYER));
  1599. if (pMsg2)
  1600. {
  1601. TSHELL_INFO(TEXT("Player 0 Pings Delete."));
  1602. memcpy( (LPVOID) pMsg2, (LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
  1603. WriteCommString( (LPVOID) pMsg2, sizeof(SPMSG_GETPLAYER));
  1604. }
  1605. }
  1606. if (m_aPlayer[iIndex].bLocal)
  1607. {
  1608. CloseHandle(m_aPlayer[iIndex].hEvent);
  1609. FlushQueue(m_aPlayer[iIndex].pid);
  1610. }
  1611. m_aPlayer[iIndex].bValid = FALSE;
  1612. LocalMsg(iIndex, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GETPLAYER));
  1613. m_dpDesc.dwCurrentPlayers--;
  1614. if (pMsg->sMsg.dwType == DPSYS_DELETEPLAYER)
  1615. {
  1616. DWORD ii, jj;
  1617. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1618. {
  1619. if ( m_aPlayer[ii].bValid == TRUE
  1620. && m_aPlayer[ii].bPlayer == FALSE
  1621. && m_aPlayer[ii].aGroup)
  1622. {
  1623. for (jj = 0; jj < MAX_PLAYERS; jj++)
  1624. {
  1625. if (m_aPlayer[ii].aGroup[jj] == pMsg->sMsg.dpId)
  1626. {
  1627. m_aPlayer[ii].aGroup[jj] = 0;
  1628. break;
  1629. }
  1630. }
  1631. }
  1632. }
  1633. }
  1634. }
  1635. }
  1636. else
  1637. {
  1638. TSHELL_INFO(TEXT("Invalid size on system message"));
  1639. }
  1640. }
  1641. break;
  1642. case DPSYS_GETPLAYER:
  1643. {
  1644. DPID pid = ((SPMSG_GETPLAYER *) lpv)->sMsg.dpId;
  1645. BOOL bFound = FALSE;
  1646. if (m_bPlayer0)
  1647. {
  1648. if ((iIndex = GetPlayerIndex((DPID) pid)) != -1)
  1649. {
  1650. SPMSG_ADDPLAYER *pMsg;
  1651. pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
  1652. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1653. pMsg->dpHdr.to = 0;
  1654. pMsg->dpHdr.from = 0;
  1655. pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
  1656. pMsg->sMsg.dwType = DPSYS_SETPLAYER;
  1657. pMsg->sMsg.dwPlayerType = m_aPlayer[iIndex].bPlayer;
  1658. pMsg->sMsg.dpId = pid;
  1659. lstrcpy( pMsg->sMsg.szShortName, m_aPlayer[iIndex].chNickName);
  1660. lstrcpy( pMsg->sMsg.szLongName, m_aPlayer[iIndex].chFullName);
  1661. WriteCommString( pMsg, sizeof(SPMSG_ADDPLAYER));
  1662. }
  1663. }
  1664. }
  1665. break;
  1666. }
  1667. }
  1668. }
  1669. VOID CImpIDP_SP::SendDesc(LPDPSESSIONDESC pDesc)
  1670. {
  1671. if (!m_bConnected || ! m_bPlayer0)
  1672. return;
  1673. TSHELL_INFO(TEXT("Here"));
  1674. SPMSG_SENDDESC *pMsg = (SPMSG_SENDDESC *) malloc(sizeof(SPMSG_SENDDESC));
  1675. if (pMsg)
  1676. {
  1677. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1678. pMsg->dpHdr.to = 0;
  1679. pMsg->dpHdr.from = 0;
  1680. pMsg->dpHdr.usCount = SIZE_SENDDESC;
  1681. pMsg->dwType = DPSYS_SENDDESC;
  1682. memcpy((LPVOID) &pMsg->dpDesc, (LPVOID) pDesc, sizeof(pMsg->dpDesc));
  1683. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_SENDDESC));
  1684. TSHELL_INFO(TEXT("Description Sent."));
  1685. }
  1686. }
  1687. VOID CImpIDP_SP::SendPing()
  1688. {
  1689. if (!m_bConnected)
  1690. {
  1691. return;
  1692. }
  1693. if ( m_dwPingSent
  1694. && (GetTickCount() < (m_dwPingSent + 2000)))
  1695. {
  1696. return;
  1697. }
  1698. else
  1699. m_dwPingSent = 0;
  1700. SPMSG_PING *pMsg = (SPMSG_PING *) malloc(sizeof(SPMSG_PING));
  1701. if (pMsg)
  1702. {
  1703. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1704. pMsg->dpHdr.to = 0;
  1705. pMsg->dpHdr.from = 0;
  1706. pMsg->dpHdr.usCount = SIZE_PING;
  1707. pMsg->dwType = DPSYS_PING;
  1708. pMsg->dwTicks = m_dwPingSent = GetTickCount();
  1709. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_PING));
  1710. }
  1711. }
  1712. VOID CImpIDP_SP::ConnectPlayers()
  1713. {
  1714. DWORD ii;
  1715. DWORD jj;
  1716. DWORD kk;
  1717. SPMSG_ADDPLAYER *pMsg;
  1718. DPMSG_ADDPLAYER dpAdd;
  1719. SPMSG_SETGROUPPLAYERS16 *pMsgG;
  1720. dpAdd.dwType = DPSYS_SETPLAYER;
  1721. dpAdd.dpId = 0;
  1722. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1723. {
  1724. if (m_aPlayer[ii].bValid && m_aPlayer[ii].bLocal)
  1725. {
  1726. pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
  1727. if (pMsg)
  1728. {
  1729. dpAdd.dpId = m_aPlayer[ii].pid;
  1730. dpAdd.dwPlayerType = m_aPlayer[ii].bPlayer;
  1731. lstrcpy( dpAdd.szShortName, m_aPlayer[ii].chNickName);
  1732. lstrcpy( dpAdd.szLongName , m_aPlayer[ii].chFullName);
  1733. pMsg->dpHdr.usCookie = SPSYS_SYS;
  1734. pMsg->dpHdr.to = (BYTE) m_aPlayer[ii].pid;
  1735. pMsg->dpHdr.from = 0;
  1736. pMsg->dpHdr.usCount = sizeof(DPMSG_ADDPLAYER);
  1737. memcpy( (LPVOID) &pMsg->sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
  1738. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
  1739. }
  1740. }
  1741. }
  1742. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1743. {
  1744. if ( m_aPlayer[ii].bValid
  1745. && m_aPlayer[ii].bLocal
  1746. && m_aPlayer[ii].bPlayer == FALSE)
  1747. {
  1748. pMsgG = (SPMSG_SETGROUPPLAYERS16 *) malloc(sizeof(SPMSG_SETGROUPPLAYERS16));
  1749. if (pMsgG)
  1750. {
  1751. pMsgG->dpHdr.usCookie = SPSYS_SYS;
  1752. pMsgG->dpHdr.to = 0;
  1753. pMsgG->dpHdr.from = 0;
  1754. pMsgG->dpHdr.usCount = sizeof(SPMSG_SETGROUPPLAYERS16) - sizeof(DPHDR);
  1755. pMsgG->dwType = DPSYS_SETGROUPPLAYER;
  1756. pMsgG->Group = (BYTE) m_aPlayer[ii].pid;
  1757. memset((LPVOID) pMsgG->bytePlayers, 0x00, 16);
  1758. kk = 0;
  1759. for (jj = 0; jj < MAX_PLAYERS && kk < 16; jj++)
  1760. {
  1761. if (m_aPlayer[ii].aGroup[jj] != 0)
  1762. pMsgG->bytePlayers[kk++] = (BYTE) m_aPlayer[ii].aGroup[jj];
  1763. }
  1764. WriteCommString( (LPVOID) pMsgG, sizeof(SPMSG_SETGROUPPLAYERS16));
  1765. }
  1766. }
  1767. }
  1768. }
  1769. VOID CImpIDP_SP::DeleteRemotePlayers()
  1770. {
  1771. DWORD ii;
  1772. DPMSG_DELETEPLAYER dpDel;
  1773. DPMSG_GENERIC dpGeneric;
  1774. dpDel.dwType = DPSYS_DELETEPLAYER;
  1775. dpGeneric.dwType = DPSYS_SESSIONLOST;
  1776. for (ii = 0; ii < MAX_PLAYERS; ii++)
  1777. {
  1778. if ( m_aPlayer[ii].bValid
  1779. && m_aPlayer[ii].bLocal == FALSE
  1780. && m_aPlayer[ii].bPlayer == TRUE)
  1781. {
  1782. m_aPlayer[ii].bValid = FALSE;
  1783. m_dpDesc.dwCurrentPlayers--;
  1784. dpDel.dpId = m_aPlayer[ii].pid;
  1785. LocalMsg(-1, (LPVOID) &dpDel, sizeof(DPMSG_DELETEPLAYER));
  1786. }
  1787. }
  1788. LocalMsg(-1, (LPVOID) &dpGeneric, sizeof(DPMSG_GENERIC));
  1789. }
  1790. VOID CImpIDP_SP::HandleConnect()
  1791. {
  1792. DPMSG_GENERIC notice;
  1793. TSHELL_INFO(TEXT("Handle Connect"));
  1794. if (!m_bConnected && m_dpDesc.dwMaxPlayers != 0)
  1795. {
  1796. TSHELL_INFO(TEXT("We are Connected.!"));
  1797. m_bConnected = TRUE;
  1798. SetEvent(m_hBlockingEvent);
  1799. }
  1800. if (m_bPlayer0)
  1801. {
  1802. SPMSG_CONNECT *pMsg = (SPMSG_CONNECT *) malloc(sizeof(SPMSG_CONNECT));
  1803. SendPing();
  1804. TSHELL_INFO(TEXT("Ping Sent."));
  1805. SendDesc(&m_dpDesc);
  1806. TSHELL_INFO(TEXT("Game Description Sent."));
  1807. if (pMsg)
  1808. {
  1809. TSHELL_INFO(TEXT("Here."));
  1810. pMsg->dpHdr.to = 0;
  1811. pMsg->dpHdr.from = 0;
  1812. pMsg->dpHdr.usCount = sizeof(SPMSG_CONNECT) - sizeof(DPHDR);
  1813. pMsg->dpHdr.usCookie = SPSYS_CONNECT;
  1814. pMsg->usVerMajor = DPVERSION_MAJOR;
  1815. pMsg->usVerMinor = DPVERSION_MINOR;
  1816. pMsg->dwConnect1 = DPSYS_KYRA;
  1817. pMsg->dwConnect2 = DPSYS_HALL;
  1818. TSHELL_INFO(TEXT("Here."));
  1819. WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_CONNECT));
  1820. notice.dwType = DPSYS_CONNECT;
  1821. TSHELL_INFO(TEXT("Here."));
  1822. AddMessage((LPVOID) &notice, sizeof(DPMSG_GENERIC), 0, 0, FALSE);
  1823. TSHELL_INFO(TEXT("Here."));
  1824. }
  1825. TSHELL_INFO(TEXT("Here."));
  1826. if (m_dpDesc.dwCurrentPlayers != 0)
  1827. {
  1828. TSHELL_INFO(TEXT("Here."));
  1829. ConnectPlayers();
  1830. TSHELL_INFO(TEXT("Current players Sent."));
  1831. }
  1832. }
  1833. TSHELL_INFO(TEXT("Leave Connect"));
  1834. return;
  1835. }