Leaked source code of windows server 2003
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.

2976 lines
74 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // Module: rdpsndc.c
  4. //
  5. // Purpose: Client-side audio redirection
  6. //
  7. // Copyright(C) Microsoft Corporation 2000
  8. //
  9. // History: 4-10-2000 vladimis [created]
  10. //
  11. /////////////////////////////////////////////////////////////////////
  12. #include "precom.h"
  13. #include <sha.h>
  14. #include <rc4.h>
  15. #include "rdpsndc.h"
  16. #undef ASSERT
  17. #ifdef DBG
  18. #undef TRC
  19. #define TRC _DbgPrintMessage
  20. #define ASSERT(Cond) if (!(Cond)) \
  21. { \
  22. ::_DbgPrintMessage( \
  23. FATAL, \
  24. _T("ASSERT in file: %s, line %d\n"), \
  25. _T(__FILE__), \
  26. __LINE__); \
  27. DebugBreak(); \
  28. }
  29. #else // !DBG
  30. #define TRC
  31. #define ASSERT
  32. #endif // !DBG
  33. #ifdef UNICODE
  34. #define _NAMEOFCLAS L"RDPSoundWnd"
  35. #else // !UNICODE
  36. #define _NAMEOFCLAS "RDPSoundWnd"
  37. #endif
  38. #define WM_WSOCK WM_USER
  39. #define WM_RESAMPLE (WM_USER + 1)
  40. #define WAVE_CLOSE_TIMEOUT 3000
  41. //
  42. // WMA codec description
  43. //
  44. #define WMAUDIO_DEC_KEY "1A0F78F0-EC8A-11d2-BBBE-006008320064"
  45. #define WAVE_FORMAT_WMAUDIO2 0x161
  46. #ifdef _WIN32
  47. #include <pshpack1.h>
  48. #else
  49. #ifndef RC_INVOKED
  50. #pragma pack(1)
  51. #endif
  52. #endif
  53. typedef struct wmaudio2waveformat_tag {
  54. WAVEFORMATEX wfx;
  55. DWORD dwSamplesPerBlock;
  56. WORD wEncodeOptions;
  57. DWORD dwSuperBlockAlign;
  58. } WMAUDIO2WAVEFORMAT;
  59. #ifdef _WIN32
  60. #include <poppack.h>
  61. #else
  62. #ifndef RC_INVOKED
  63. #pragma pack()
  64. #endif
  65. #endif
  66. // Trace levels
  67. //
  68. const TCHAR *ALV = _T("TSSNDC - ALV:");
  69. const TCHAR *INF = _T("TSSNDC - INF:");
  70. const TCHAR *WRN = _T("TSSNDC - WRN:");
  71. const TCHAR *ERR = _T("TSSNDC - ERR:");
  72. const TCHAR *FATAL = _T("TSSNDC - !FATAL!:");
  73. /*
  74. * Function declarations
  75. *
  76. */
  77. VOID
  78. VCAPITYPE
  79. OpenEventFnEx(
  80. IN PVOID lpUserParam,
  81. IN DWORD OpenHandle,
  82. IN UINT event,
  83. IN PVOID pData,
  84. IN UINT32 dataLength,
  85. IN UINT32 totalLength,
  86. IN UINT32 dataFlags
  87. );
  88. INT
  89. WSInit(
  90. VOID
  91. );
  92. LRESULT
  93. CALLBACK
  94. MsgWndProc(
  95. HWND hwnd,
  96. UINT uiMessage,
  97. WPARAM wParam,
  98. LPARAM lParam
  99. );
  100. VOID
  101. _cdecl
  102. _DbgPrintMessage(
  103. LPCTSTR level,
  104. LPCTSTR format,
  105. ...
  106. );
  107. //////////////////////////////////////////////////////////////////////////
  108. /*
  109. * Function:
  110. * OpenEventFn
  111. *
  112. * Description:
  113. * Called by the TS client on channel read/write ready
  114. *
  115. * Parameters:
  116. * lpUserParam - parameter passed from VirtualChannelEntryEx
  117. * OpenaHandle - Channel handle, returned by VirtualChanneOpen
  118. * event - event type
  119. * pData - meaning depends on event type
  120. * dataLength - size of pData
  121. * dataFlags - information about the received data
  122. *
  123. */
  124. VOID
  125. VCAPITYPE
  126. OpenEventFnEx(
  127. IN PVOID lpUserParam,
  128. IN DWORD OpenHandle,
  129. IN UINT event,
  130. IN PVOID pData,
  131. IN UINT32 dataLength,
  132. IN UINT32 totalLength,
  133. IN UINT32 dataFlags
  134. )
  135. {
  136. CRDPSound *pSnd;
  137. ASSERT( NULL != lpUserParam );
  138. if ( NULL != lpUserParam )
  139. {
  140. pSnd = ((VCManager*)lpUserParam)->GetSound();
  141. ASSERT( NULL != pSnd );
  142. if ( NULL != pSnd )
  143. pSnd->OpenEventFn(
  144. OpenHandle,
  145. event,
  146. pData,
  147. dataLength,
  148. totalLength,
  149. dataFlags
  150. );
  151. }
  152. }
  153. LRESULT
  154. CALLBACK
  155. MsgWndProc(
  156. HWND hwnd,
  157. UINT uiMessage,
  158. WPARAM wParam,
  159. LPARAM lParam
  160. )
  161. {
  162. LRESULT rv = 0;
  163. CRDPSound *pSnd;
  164. pSnd = (CRDPSound *)
  165. #ifndef OS_WINCE
  166. GetWindowLongPtr( hwnd, GWLP_USERDATA );
  167. #else // OS_WINCE
  168. GetWindowLong( hwnd, GWL_USERDATA );
  169. #endif
  170. switch (uiMessage)
  171. {
  172. case MM_WOM_OPEN:
  173. ASSERT( NULL != pSnd );
  174. if ( NULL != pSnd )
  175. pSnd->vcwaveCallback( (HWAVEOUT)wParam, WOM_OPEN, NULL );
  176. break;
  177. case MM_WOM_CLOSE:
  178. ASSERT( NULL != pSnd );
  179. if ( NULL != pSnd )
  180. pSnd->vcwaveCallback( (HWAVEOUT)wParam, WOM_CLOSE, NULL );
  181. break;
  182. case MM_WOM_DONE:
  183. ASSERT( NULL != pSnd );
  184. if ( NULL != pSnd )
  185. pSnd->vcwaveCallback((HWAVEOUT)wParam, WOM_DONE, (LPWAVEHDR)lParam);
  186. break;
  187. case WM_RESAMPLE:
  188. ASSERT( NULL != pSnd );
  189. if ( NULL != pSnd )
  190. pSnd->vcwaveResample();
  191. break;
  192. case WM_WSOCK:
  193. ASSERT( NULL != pSnd );
  194. pSnd->DGramSocketMessage(wParam, lParam);
  195. break;
  196. case WM_DESTROY:
  197. PostQuitMessage(0);
  198. break;
  199. default:
  200. rv = DefWindowProc(hwnd, uiMessage, wParam, lParam);
  201. }
  202. return rv;
  203. }
  204. /*
  205. * Function:
  206. * InitEventFn
  207. *
  208. * Description:
  209. * Called by InitEventFn
  210. *
  211. * Parameters:
  212. * pInitHandle - connection handle
  213. * event - Event id
  214. * pData - Data, meaning depends on event id
  215. * dataLength - Length of data
  216. * (see MSDN: VirtualChannelInitEvent)
  217. *
  218. */
  219. VOID
  220. CRDPSound::InitEventFn(
  221. PVOID pInitHandle,
  222. UINT event,
  223. PVOID pData,
  224. UINT dataLength
  225. )
  226. {
  227. UINT rc;
  228. UNREFERENCED_PARAMETER(dataLength);
  229. ASSERT( pInitHandle == m_pInitHandle );
  230. switch(event)
  231. {
  232. case CHANNEL_EVENT_INITIALIZED:
  233. TRC(ALV, _T("InitEventFnEx: CHANNEL_EVENT_INITILIZED\n"));
  234. ::WSInit();
  235. /*
  236. #ifdef OS_WINCE
  237. #error create single instance
  238. ::WSAStartAsyncThread();
  239. #endif // OS_WINCE
  240. */
  241. CreateMsgWindow(m_hInst);
  242. break;
  243. case CHANNEL_EVENT_CONNECTED:
  244. TRC(ALV, _T("InitEventFnEx: CHANNEL_EVENT_CONNECTED to %s\n"), pData);
  245. ASSERT(m_ChannelEntries.pVirtualChannelOpenEx);
  246. rc = (m_ChannelEntries.pVirtualChannelOpenEx)(
  247. pInitHandle,
  248. &m_dwChannel,
  249. _SNDVC_NAME,
  250. OpenEventFnEx
  251. );
  252. if (rc != CHANNEL_RC_OK)
  253. {
  254. TRC(WRN, _T("InitEventFnEx: VirtualChannelOpen returned %d\n"), rc);
  255. m_dwChannel = INVALID_CHANNELID;
  256. } else {
  257. // All's OK, check the channel handle
  258. //
  259. ASSERT(m_dwChannel != INVALID_CHANNELID);
  260. }
  261. // Prepare for connectionless data
  262. //
  263. DGramInit();
  264. break;
  265. case CHANNEL_EVENT_DISCONNECTED:
  266. TRC(ALV, _T("InitEventFnEx: CHANNEL_EVENT_DISCONNECTED\n"));
  267. ASSERT(m_ChannelEntries.pVirtualChannelCloseEx);
  268. if (m_dwChannel != INVALID_CHANNELID)
  269. {
  270. rc = m_ChannelEntries.pVirtualChannelCloseEx(
  271. m_pInitHandle,
  272. m_dwChannel
  273. );
  274. if (rc != CHANNEL_RC_OK)
  275. {
  276. TRC(WRN, _T("InitEventFnEx: VirtualChannelClose returned %d\n"), rc);
  277. }
  278. m_dwChannel = INVALID_CHANNELID;
  279. if (NULL != m_hWave)
  280. {
  281. waveOutReset(m_hWave);
  282. vcwaveClose();
  283. }
  284. }
  285. // destroy the UDP socket
  286. //
  287. DGramDone();
  288. m_bPrologReceived = FALSE;
  289. m_dwBytesInProlog = 0;
  290. m_dwBytesInBody = 0;
  291. //
  292. // dispose the cache format
  293. //
  294. vcwaveCleanSoundFormats();
  295. vcwaveFreeAllWaves();
  296. _FragSlotFreeAll();
  297. break;
  298. case CHANNEL_EVENT_V1_CONNECTED:
  299. TRC(ALV, _T("InitEventFnEx: CHANNEL_EVENT_V1_CONNECTED\n"));
  300. break;
  301. case CHANNEL_EVENT_TERMINATED:
  302. TRC(ALV, _T("InitEventFnEx: CHANNEL_EVENT_TERMINATED\n"));
  303. WSACleanup();
  304. if (NULL != m_hWave)
  305. {
  306. waveOutReset(m_hWave);
  307. vcwaveClose();
  308. }
  309. DGramDone();
  310. /*
  311. #ifdef OS_WINCE
  312. #error see previous error
  313. ::WSACloseAsyncThread();
  314. #endif // OS_WINCE
  315. */
  316. if ( NULL != m_pProlog )
  317. {
  318. free( m_pProlog );
  319. m_pProlog = NULL;
  320. }
  321. if ( NULL != m_pMsgBody )
  322. {
  323. free( m_pMsgBody );
  324. m_pMsgBody = NULL;
  325. }
  326. vcwaveCleanSoundFormats();
  327. vcwaveFreeAllWaves();
  328. _FragSlotFreeAll();
  329. DestroyMsgWindow();
  330. break;
  331. default:
  332. TRC(ALV, _T("Unhandled event in InitEventFnEx: %d\n"), event);
  333. }
  334. }
  335. /*
  336. * Function:
  337. * OpenEventFn
  338. *
  339. * Description:
  340. * Called by OpenEventFnEx
  341. *
  342. * Parameters:
  343. * OpenaHandle - Channel handle, returned by VirtualChanneOpen
  344. * event - event type
  345. * pData - meaning depends on event type
  346. * dataLength - size of pData
  347. * dataFlags - information about the received data
  348. *
  349. */
  350. VOID
  351. CRDPSound::OpenEventFn(
  352. DWORD OpenHandle,
  353. UINT event,
  354. PVOID pData,
  355. UINT32 dataLength,
  356. UINT32 totalLength,
  357. UINT32 dataFlags
  358. )
  359. {
  360. UNREFERENCED_PARAMETER(OpenHandle);
  361. switch (event)
  362. {
  363. case CHANNEL_EVENT_DATA_RECEIVED:
  364. #if _IO_DBG
  365. TRC(ALV,
  366. "OpenEventFn: CHANNEL_EVENT_DATA_RECEIVED, dataSize=0x%x, total=0x%x\n",
  367. dataLength,
  368. totalLength);
  369. #endif
  370. //
  371. // save the data in global buffers
  372. //
  373. if (!m_bPrologReceived)
  374. {
  375. //
  376. // receive the prolog (1st message)
  377. //
  378. if ( 0 != ( dataFlags & CHANNEL_FLAG_FIRST ))
  379. m_dwBytesInProlog = 0;
  380. if ( NULL == m_pProlog )
  381. {
  382. ASSERT( 0 != ( dataFlags & CHANNEL_FLAG_FIRST ));
  383. m_pProlog = malloc( totalLength );
  384. if ( NULL == m_pProlog )
  385. {
  386. TRC( FATAL, _T("OpenEventFn: failed to allocate %d bytes\n"),
  387. totalLength);
  388. break;
  389. }
  390. m_dwPrologAllocated = totalLength;
  391. }
  392. if ( totalLength > m_dwPrologAllocated )
  393. {
  394. PVOID pNewProlog;
  395. ASSERT( 0 != ( dataFlags & CHANNEL_FLAG_FIRST ));
  396. pNewProlog = realloc( m_pProlog, totalLength );
  397. if ( NULL == pNewProlog )
  398. {
  399. TRC( FATAL, _T("OpenEventFn: failed to allocate %d bytes\n"),
  400. totalLength);
  401. free ( m_pProlog );
  402. m_pProlog = NULL;
  403. m_dwPrologAllocated = 0;
  404. break;
  405. }
  406. m_pProlog = pNewProlog;
  407. m_dwPrologAllocated = totalLength;
  408. }
  409. if ( m_dwBytesInProlog + dataLength > m_dwPrologAllocated )
  410. {
  411. TRC( ERR, _T("An invalid VC packet received. Ignoring\n" ));
  412. break;
  413. }
  414. memcpy( ((LPSTR)m_pProlog) + m_dwBytesInProlog, pData, dataLength );
  415. m_dwBytesInProlog += dataLength;
  416. ASSERT( m_dwBytesInProlog <= totalLength );
  417. if ( 0 != ( dataFlags & CHANNEL_FLAG_LAST ))
  418. {
  419. m_bPrologReceived = TRUE;
  420. ASSERT( sizeof(SNDPROLOG) <= m_dwBytesInProlog );
  421. //
  422. // check if we expect a body
  423. //
  424. ASSERT( m_dwBytesInProlog - sizeof(SNDPROLOG) <=
  425. ((PSNDPROLOG)m_pProlog)->BodySize);
  426. if ( m_dwBytesInProlog - sizeof(SNDPROLOG) ==
  427. ((PSNDPROLOG)m_pProlog)->BodySize )
  428. {
  429. // no, proceed the message
  430. //
  431. DataArrived(
  432. (PSNDPROLOG)m_pProlog,
  433. ((PSNDPROLOG)m_pProlog) + 1
  434. );
  435. m_bPrologReceived = FALSE;
  436. m_dwBytesInProlog = 0;
  437. m_dwBytesInBody = 0;
  438. }
  439. }
  440. } else {
  441. //
  442. // receive the body (2nd message)
  443. //
  444. if ( 0 != ( dataFlags & CHANNEL_FLAG_FIRST ))
  445. m_dwBytesInBody = 0;
  446. if ( NULL == m_pMsgBody )
  447. {
  448. ASSERT( 0 != ( dataFlags & CHANNEL_FLAG_FIRST ));
  449. m_pMsgBody = malloc( totalLength );
  450. if ( NULL == m_pMsgBody )
  451. {
  452. TRC( FATAL, _T("OpenEventFn: failed to allocate %d bytes\n"),
  453. totalLength);
  454. break;
  455. }
  456. m_dwBodyAllocated = totalLength;
  457. }
  458. if ( totalLength > m_dwBodyAllocated )
  459. {
  460. PVOID pNewBody;
  461. ASSERT( 0 != ( dataFlags & CHANNEL_FLAG_FIRST ));
  462. pNewBody = realloc( m_pMsgBody, totalLength );
  463. if ( NULL == pNewBody )
  464. {
  465. TRC( FATAL, _T("OpenEventFn: failed to allocate %d bytes\n"),
  466. totalLength);
  467. free ( m_pMsgBody );
  468. m_pMsgBody = NULL;
  469. m_dwBodyAllocated = 0;
  470. break;
  471. }
  472. m_pMsgBody = pNewBody;
  473. m_dwBodyAllocated = totalLength;
  474. }
  475. if ( m_dwBytesInBody + dataLength > m_dwBodyAllocated )
  476. {
  477. TRC( ERR, _T("An invalid VC packet received. Ignoring\n" ));
  478. break;
  479. }
  480. memcpy( ((LPSTR)m_pMsgBody) + m_dwBytesInBody, pData, dataLength );
  481. m_dwBytesInBody += dataLength;
  482. ASSERT( m_dwBytesInBody <= totalLength );
  483. if ( 0 != ( dataFlags & CHANNEL_FLAG_LAST ))
  484. {
  485. UINT32 *pdw;
  486. //
  487. // here comes the magic
  488. // the server sends two packets, but it is possible
  489. // in case of switching between sessions (or shadowing ?!)
  490. // that the client can receive first packet from one session
  491. // and the second from another
  492. // that's why we have a valid message type for each packet
  493. // by replacing the first word of the second message
  494. // this word is kept in the end of the first message
  495. //
  496. if ( NULL != m_pMsgBody &&
  497. SNDC_NONE != *((UINT32 *)m_pMsgBody) )
  498. {
  499. LPVOID pSwap;
  500. DWORD dwSwap;
  501. TRC(ERR, _T("OpenEventFn: messages not synchronized. ")
  502. _T("Trying to fix it\n"));
  503. pSwap = m_pProlog;
  504. m_pProlog = m_pMsgBody;
  505. m_pMsgBody = pSwap;
  506. dwSwap = m_dwPrologAllocated;
  507. m_dwPrologAllocated = m_dwBodyAllocated;
  508. m_dwBodyAllocated = dwSwap;
  509. m_dwBytesInProlog = m_dwBytesInBody;
  510. m_dwBytesInBody = 0;
  511. // we swapped the body and the prolog
  512. // now, wait for the actual body
  513. //
  514. break;
  515. }
  516. //
  517. // from the end of the prolog message, remove
  518. // UINT32 word and place it at the begining of the body
  519. //
  520. ASSERT( sizeof(SNDPROLOG) + sizeof(UINT32) <= m_dwBytesInProlog);
  521. if ( sizeof(SNDPROLOG) + sizeof(UINT32) > m_dwBytesInProlog )
  522. {
  523. TRC( ERR, _T("An invalid VC packet received. Ignoring\n" ));
  524. break;
  525. }
  526. pdw = (UINT32 *)(((LPSTR)m_pProlog) +
  527. m_dwBytesInProlog - sizeof(UINT32));
  528. *((UINT32 *)m_pMsgBody) = *pdw;
  529. //
  530. // cut the prolog length by UINT32 size
  531. //
  532. m_dwBytesInProlog -= sizeof(UINT32);
  533. DataArrived(
  534. (PSNDPROLOG)m_pProlog,
  535. m_pMsgBody
  536. );
  537. m_bPrologReceived = FALSE;
  538. m_dwBytesInProlog = 0;
  539. m_dwBytesInBody = 0;
  540. }
  541. }
  542. break;
  543. case CHANNEL_EVENT_WRITE_COMPLETE:
  544. {
  545. TRC(ALV, _T("OpenEventFn: CHANNEL_EVENT_WRITE_COMPLETE, ptr=0x%p\n"),
  546. pData);
  547. free(pData);
  548. }
  549. break;
  550. case CHANNEL_EVENT_WRITE_CANCELLED:
  551. {
  552. TRC(WRN, _T("OpenEventFn: CHANNEL_EVENT_WRITE_CANCELED. Cleaning up\n"));
  553. free(pData);
  554. }
  555. break;
  556. default:
  557. TRC(ALV, _T("Unhandled event in OpenEventFn: %d\n"), event);
  558. }
  559. }
  560. /*
  561. * Function:
  562. * ChannelWriteNCopy
  563. *
  564. * Description:
  565. * Allocates a chunk of memory and sends it using ChannelWrite
  566. * Allows the caller to free or reuse the buffer
  567. *
  568. * Parameters:
  569. * pBuffer - Chunk pointer
  570. * uiSize - Chunk size
  571. *
  572. * Returns:
  573. * TRUE on success
  574. *
  575. */
  576. BOOL
  577. CRDPSound::ChannelWriteNCopy(
  578. LPVOID pBuffer,
  579. UINT32 uiSize
  580. )
  581. {
  582. BOOL rv = FALSE;
  583. LPVOID pSendBuffer = NULL;
  584. if ( INVALID_CHANNELID == m_dwChannel )
  585. {
  586. TRC(ERR, _T("ChannelWriteNCopy: invalid handle\n"));
  587. goto exitpt;
  588. }
  589. if (NULL == pBuffer)
  590. {
  591. TRC(ERR, _T("ChannelWriteNCopy: buffer is NULL\n"));
  592. goto exitpt;
  593. }
  594. pSendBuffer = malloc(uiSize);
  595. if (pSendBuffer)
  596. {
  597. memcpy(pSendBuffer, pBuffer, uiSize);
  598. rv = ChannelWrite( pSendBuffer, uiSize );
  599. }
  600. exitpt:
  601. if (!rv)
  602. {
  603. if (pSendBuffer)
  604. free(pSendBuffer);
  605. }
  606. return rv;
  607. }
  608. /*
  609. * Function:
  610. * DataArrived
  611. *
  612. * Description:
  613. * Processes a message arrived from the channel
  614. *
  615. * Parameters:
  616. * pProlog - the message prolog, type and body size
  617. * pBody - pointer to the message body
  618. *
  619. */
  620. VOID
  621. CRDPSound::DataArrived(
  622. PSNDPROLOG pProlog,
  623. LPVOID pBody
  624. )
  625. {
  626. ASSERT(pProlog);
  627. ASSERT(pBody);
  628. switch(pProlog->Type)
  629. {
  630. case SNDC_CLOSE:
  631. TRC(ALV, _T("DataArrived: SNDC_CLOSE\n"));
  632. if (m_hWave)
  633. {
  634. vcwaveClose();
  635. }
  636. break;
  637. case SNDC_SETVOLUME:
  638. {
  639. PSNDSETVOLUME pSetVolume;
  640. TRC(ALV, _T("DataArrived: SNDC_SETVOLUME\n"));
  641. if ( pProlog->BodySize < sizeof( *pSetVolume ) - sizeof( *pProlog ))
  642. {
  643. TRC( ERR, _T("DataArrived: Invalid SNDC_SETVOLUME message\n" ));
  644. break;
  645. }
  646. pSetVolume = (PSNDSETVOLUME)
  647. (((LPSTR)pBody) - sizeof(*pProlog));
  648. ASSERT(pProlog->BodySize == sizeof(*pSetVolume) - sizeof(*pProlog));
  649. if (m_hWave)
  650. waveOutSetVolume(m_hWave, pSetVolume->dwVolume);
  651. }
  652. break;
  653. case SNDC_WAVE:
  654. {
  655. PSNDWAVE pWave;
  656. //
  657. // disable dgram response
  658. //
  659. m_dwRemoteDGramPort = 0;
  660. m_ulRemoteDGramAddress = 0;
  661. pWave = (PSNDWAVE)pProlog;
  662. TRC(ALV, _T("DataArrived: SNDC_WAVE, block no: %d\n"),
  663. pWave->cBlockNo);
  664. if ( pProlog->BodySize < sizeof( *pWave ) - sizeof( *pProlog ))
  665. {
  666. TRC( ERR, _T("DataArrived: Invalid SNDC_WAVE message\n" ));
  667. break;
  668. }
  669. vcwaveWrite(pWave->cBlockNo,
  670. pWave->wFormatNo,
  671. pWave->wTimeStamp,
  672. pWave->Prolog.BodySize - sizeof(SNDWAVE) + sizeof(SNDPROLOG),
  673. pBody);
  674. }
  675. break;
  676. case SNDC_TRAINING:
  677. {
  678. SNDTRAINING SndTraining;
  679. PSNDTRAINING pRecvTraining;
  680. if ( pProlog->BodySize < sizeof( *pRecvTraining ) - sizeof( *pProlog ))
  681. {
  682. TRC( ERR, _T("DataArrived: Invalid SNDC_TRAINING message\n" ));
  683. break;
  684. }
  685. //
  686. // disable dgram response
  687. //
  688. m_dwRemoteDGramPort = 0;
  689. m_ulRemoteDGramAddress = 0;
  690. pRecvTraining = (PSNDTRAINING)
  691. (((LPSTR)pBody) - sizeof(*pProlog));
  692. TRC(ALV, _T("DataArrived: training, sending a response\n"));
  693. SndTraining.Prolog.Type = SNDC_TRAINING;
  694. SndTraining.Prolog.BodySize = sizeof(SndTraining) -
  695. sizeof(SndTraining.Prolog);
  696. SndTraining.wTimeStamp = pRecvTraining->wTimeStamp;
  697. SndTraining.wPackSize = pRecvTraining->wPackSize;
  698. //
  699. // send the response immediatly
  700. //
  701. ChannelWriteNCopy( &SndTraining, sizeof(SndTraining) );
  702. }
  703. break;
  704. case SNDC_FORMATS:
  705. {
  706. PSNDFORMATMSG pSndFormats;
  707. PSNDFORMATMSG pSndFormatsResp;
  708. PSNDFORMATITEM pSndSuppFormats = NULL;
  709. DWORD dwRespSize;
  710. DWORD dwListSize;
  711. DWORD dwNumFormats;
  712. BOOL bSuccess;
  713. DWORD dwPacketSize;
  714. DWORD count;
  715. PSNDFORMATITEM pFmt;
  716. pSndFormats = (PSNDFORMATMSG)
  717. (((LPSTR)pBody) - sizeof(*pProlog));
  718. TRC(ALV, _T("DataArrived: SNDC_FORMATS, number of formats: %d\n"),
  719. pSndFormats->wNumberOfFormats);
  720. if ( pProlog->BodySize < sizeof( *pSndFormats ) - sizeof( *pProlog ))
  721. {
  722. TRC( ERR, _T("DataArrived: Invalid SNDC_FORMATS message\n" ));
  723. break;
  724. }
  725. //
  726. // validate the packet length
  727. //
  728. dwPacketSize = pProlog->BodySize - sizeof( *pSndFormats ) + sizeof( *pProlog );
  729. pFmt = (PSNDFORMATITEM) (pSndFormats + 1);
  730. for( count = 0; count < pSndFormats->wNumberOfFormats; count ++ )
  731. {
  732. DWORD adv = sizeof( *pFmt ) + pFmt->cbSize;
  733. if ( adv > dwPacketSize )
  734. {
  735. TRC( ERR, _T("DataArrived: Invalid SNDC_FORMATS, invalid format list\n" ));
  736. goto break_sndformat;
  737. }
  738. pFmt = (PSNDFORMATITEM)((LPSTR)pFmt + adv);
  739. dwPacketSize -= adv;
  740. }
  741. ASSERT( 0 == dwPacketSize );
  742. m_cLastReceivedBlock = pSndFormats->cLastBlockConfirmed;
  743. vcwaveCleanSoundFormats();
  744. bSuccess = vcwaveChooseSoundFormat(
  745. pSndFormats->wNumberOfFormats,
  746. (PSNDFORMATITEM) (pSndFormats + 1),
  747. &pSndSuppFormats,
  748. &dwListSize,
  749. &dwNumFormats
  750. );
  751. if (bSuccess)
  752. {
  753. ASSERT( NULL != pSndSuppFormats );
  754. ASSERT( 0 != dwListSize );
  755. ASSERT( 0 != dwNumFormats );
  756. bSuccess = vcwaveSaveSoundFormats(
  757. pSndSuppFormats,
  758. dwNumFormats);
  759. if (!bSuccess)
  760. {
  761. free(pSndSuppFormats);
  762. pSndSuppFormats = NULL;
  763. dwNumFormats = 0;
  764. dwListSize = 0;
  765. }
  766. } else {
  767. ASSERT( NULL == pSndSuppFormats );
  768. ASSERT( 0 == dwListSize );
  769. ASSERT( 0 == dwNumFormats );
  770. }
  771. dwRespSize = sizeof( *pSndFormatsResp ) + dwListSize;
  772. __try {
  773. pSndFormatsResp = (PSNDFORMATMSG)alloca( dwRespSize );
  774. }
  775. __except((EXCEPTION_STACK_OVERFLOW == GetExceptionCode()) ?
  776. EXCEPTION_EXECUTE_HANDLER :
  777. EXCEPTION_CONTINUE_SEARCH)
  778. {
  779. _resetstkoflw();
  780. pSndFormatsResp = NULL;
  781. TRC(ERR, _T("alloca threw exception: 0x%x\n"),
  782. GetExceptionCode());
  783. }
  784. if ( NULL == pSndFormatsResp )
  785. goto break_sndformat;
  786. pSndFormatsResp->Prolog.Type = SNDC_FORMATS;
  787. pSndFormatsResp->Prolog.BodySize = (UINT16)(
  788. dwRespSize -
  789. sizeof( pSndFormatsResp->Prolog ));
  790. pSndFormatsResp->wNumberOfFormats = (WORD)dwNumFormats;
  791. vcwaveGetDevCaps( pSndFormatsResp );
  792. //
  793. // Beta 1 compatability, fake we are version 1 if the server is version 1
  794. //
  795. m_wServerVersion = pSndFormats->wVersion;
  796. if ( 1 == pSndFormats->wVersion )
  797. pSndFormatsResp->wVersion = 1;
  798. else
  799. pSndFormatsResp->wVersion = RDPSND_PROTOCOL_VERSION;
  800. //
  801. // copy the format list
  802. //
  803. memcpy( (PSNDFORMATITEM) ( pSndFormatsResp + 1 ),
  804. pSndSuppFormats,
  805. dwListSize );
  806. ChannelWriteNCopy( pSndFormatsResp, dwRespSize );
  807. break_sndformat:
  808. if ( NULL != pSndSuppFormats )
  809. free ( pSndSuppFormats );
  810. }
  811. break;
  812. case SNDC_CRYPTKEY:
  813. {
  814. PSNDCRYPTKEY pKey = (PSNDCRYPTKEY)(((LPSTR)pBody) - sizeof(*pProlog));
  815. if ( pProlog->BodySize < sizeof( *pKey ) - sizeof( *pProlog ))
  816. {
  817. TRC( ERR, _T("DataArrived: Invalid SNDC_CRYPTKEY message\n"));
  818. break;
  819. }
  820. memcpy( m_EncryptKey, pKey->Seed, RANDOM_KEY_LENGTH );
  821. }
  822. break;
  823. default:
  824. TRC(ERR, _T("DataArrived: Invalid message type received: %d\n"), pProlog->Type);
  825. }
  826. }
  827. /*
  828. * Function:
  829. * vcwaveResample
  830. *
  831. * Description:
  832. * Reopens the device with new codec
  833. *
  834. */
  835. VOID
  836. CRDPSound::vcwaveResample(
  837. VOID
  838. )
  839. {
  840. if ( 0 != m_dwWavesPlaying || NULL == m_pFirstWave )
  841. goto exitpt;
  842. if ( NULL == m_hWave ||
  843. m_dwCurrentFormat != (DWORD)PtrToLong((PVOID)m_pFirstWave->reserved))
  844. {
  845. TRC(INF, _T("vcwaveResample: Resampling\n"));
  846. m_dwCurrentFormat = (DWORD)PtrToLong((PVOID)m_pFirstWave->reserved);
  847. if ( m_dwCurrentFormat >= m_dwNumFormats )
  848. {
  849. TRC(ERR, _T("vcwaveResample: invalid format no\n"));
  850. vcwaveFreeAllWaves();
  851. goto exitpt;
  852. }
  853. vcwaveOpen( (LPWAVEFORMATEX)m_ppFormats[ m_dwCurrentFormat ] );
  854. }
  855. //
  856. // stuff all pending blocks
  857. //
  858. while ( NULL != m_pFirstWave &&
  859. m_dwCurrentFormat == (DWORD)PtrToLong( (PVOID)m_pFirstWave->reserved ))
  860. {
  861. LPWAVEHDR lpNext = m_pFirstWave->lpNext;
  862. MMRESULT mmres;
  863. mmres = vcwaveOutWrite( m_pFirstWave );
  864. if ( MMSYSERR_NOERROR != mmres )
  865. {
  866. vcwaveFreeAllWaves();
  867. } else {
  868. m_pFirstWave = lpNext;
  869. if ( NULL == m_pFirstWave )
  870. m_pLastWave = NULL;
  871. }
  872. }
  873. exitpt:
  874. ;
  875. }
  876. /*
  877. * Function:
  878. * DGramSocketMessage
  879. *
  880. * Description:
  881. * Callback from UDP
  882. *
  883. */
  884. VOID
  885. CRDPSound::DGramSocketMessage(
  886. WPARAM wParam,
  887. LPARAM lParam
  888. )
  889. {
  890. if (WSAGETSELECTERROR(lParam))
  891. {
  892. TRC(ERR, _T("WM_WSOCK: Winsock error: %d\n"),
  893. WSAGETSELECTERROR(lParam));
  894. goto exitpt;
  895. }
  896. if (m_hDGramSocket != (SOCKET)wParam)
  897. {
  898. TRC(WRN, _T("WM_WSOCK: message for unknown socket\n"));
  899. goto exitpt;
  900. }
  901. if (WSAGETSELECTEVENT(lParam) == FD_CLOSE)
  902. {
  903. TRC(ERR, _T("WM_WSOCK: socket closed\n"));
  904. DGramDone();
  905. goto exitpt;
  906. }
  907. if (WSAGETSELECTEVENT(lParam) != FD_READ)
  908. {
  909. TRC(WRN, _T("WM_WSOCK: unknown event received\n"));
  910. goto exitpt;
  911. }
  912. TRC(ALV, _T("WM_WSOCK: data available\n"));
  913. {
  914. BOOL bSuccess;
  915. PSNDWAVE pSndWave;
  916. UINT structsize;
  917. structsize = sizeof(*pSndWave) + TSSND_BLOCKSIZE + RDPSND_SIGNATURE_SIZE;
  918. __try
  919. {
  920. pSndWave = (PSNDWAVE)alloca(structsize);
  921. }
  922. __except((EXCEPTION_STACK_OVERFLOW == GetExceptionCode()) ?
  923. EXCEPTION_EXECUTE_HANDLER :
  924. EXCEPTION_CONTINUE_SEARCH)
  925. {
  926. _resetstkoflw();
  927. pSndWave = NULL;
  928. TRC(ERR, _T("WM_SOCK: alloca threw exception: 0x%x\n"),
  929. GetExceptionCode());
  930. }
  931. if (NULL == pSndWave)
  932. goto exitpt;
  933. bSuccess = DGramRecvWave(
  934. pSndWave,
  935. structsize
  936. );
  937. if (bSuccess)
  938. {
  939. PBYTE pWave = (PBYTE)(pSndWave+1);
  940. UINT uiWaveSize = pSndWave->Prolog.BodySize -
  941. sizeof(SNDWAVE) + sizeof(SNDPROLOG);
  942. if ( IsDGramWaveSigned( m_wServerVersion ))
  943. {
  944. DWORD dw;
  945. BYTE Signature[ RDPSND_SIGNATURE_SIZE ];
  946. //
  947. // wave starts with signature
  948. //
  949. if ( uiWaveSize < RDPSND_SIGNATURE_SIZE )
  950. {
  951. TRC( ERR, _T("Insufficient data for signature\n" ));
  952. goto exitpt;
  953. }
  954. if ( !IsDGramWaveAudioSigned( m_wServerVersion ))
  955. {
  956. SL_Signature( Signature, pSndWave->dwBlockNo );
  957. } else {
  958. SL_AudioSignature( Signature,
  959. pSndWave->dwBlockNo,
  960. pWave + RDPSND_SIGNATURE_SIZE,
  961. uiWaveSize - RDPSND_SIGNATURE_SIZE );
  962. }
  963. dw = memcmp( pWave, Signature, RDPSND_SIGNATURE_SIZE );
  964. if ( 0 != dw )
  965. {
  966. TRC( ERR, _T("Invalid signature\n" ));
  967. goto exitpt;
  968. }
  969. pWave += RDPSND_SIGNATURE_SIZE;
  970. uiWaveSize -= RDPSND_SIGNATURE_SIZE;
  971. }
  972. vcwaveWrite(pSndWave->cBlockNo,
  973. pSndWave->wFormatNo,
  974. pSndWave->wTimeStamp,
  975. uiWaveSize,
  976. pWave);
  977. }
  978. }
  979. exitpt:
  980. ;
  981. }
  982. /*
  983. * Function:
  984. * CreateMsgWindow
  985. *
  986. * Description:
  987. * Creates a window
  988. *
  989. */
  990. BOOL
  991. CRDPSound::CreateMsgWindow(
  992. HINSTANCE hInstance
  993. )
  994. {
  995. WNDCLASS wc;
  996. BOOL rv = FALSE;
  997. DWORD dwLastErr;
  998. LONG_PTR dwUser;
  999. memset(&wc, 0, sizeof(wc));
  1000. wc.lpfnWndProc = MsgWndProc;
  1001. wc.hInstance = hInstance;
  1002. wc.lpszClassName = _NAMEOFCLAS;
  1003. if (!RegisterClass (&wc))
  1004. {
  1005. dwLastErr = GetLastError();
  1006. if(dwLastErr != ERROR_CLASS_ALREADY_EXISTS)
  1007. {
  1008. TRC(ERR,
  1009. _T("CreateMsgWindow: Can't register class. GetLastError=%d\n"),
  1010. GetLastError());
  1011. goto exitpt;
  1012. }
  1013. }
  1014. m_hMsgWindow = CreateWindow(
  1015. _NAMEOFCLAS,
  1016. NULL, // Window name
  1017. 0, // dwStyle
  1018. 0, // x
  1019. 0, // y
  1020. 0, // nWidth
  1021. 0, // nHeight
  1022. NULL, // hWndParent
  1023. NULL, // hMenu
  1024. hInstance,
  1025. NULL); // lpParam
  1026. if (!m_hMsgWindow)
  1027. {
  1028. TRC(ERR, _T("CreateMsgWindow: Failed to create message window. GetLastError=%d\n"),
  1029. GetLastError());
  1030. goto exitpt;
  1031. }
  1032. //
  1033. // safe the class pointer in the window structure
  1034. //
  1035. #ifndef OS_WINCE
  1036. dwUser = SetWindowLongPtr(
  1037. m_hMsgWindow,
  1038. GWLP_USERDATA,
  1039. (LONG_PTR)this
  1040. );
  1041. #else
  1042. dwUser = SetWindowLong(
  1043. m_hMsgWindow,
  1044. GWL_USERDATA,
  1045. (LONG)this
  1046. );
  1047. #endif
  1048. ASSERT( 0 == dwUser );
  1049. rv = TRUE;
  1050. exitpt:
  1051. return rv;
  1052. }
  1053. /*
  1054. * Function:
  1055. * DestroyMsgWindow
  1056. *
  1057. * Description:
  1058. * Destroy our window
  1059. *
  1060. */
  1061. VOID
  1062. CRDPSound::DestroyMsgWindow(
  1063. VOID
  1064. )
  1065. {
  1066. if (NULL != m_hMsgWindow)
  1067. DestroyWindow(m_hMsgWindow);
  1068. UnregisterClass(_NAMEOFCLAS, m_hInst);
  1069. }
  1070. /*
  1071. * Function:
  1072. * ChannelWrite
  1073. *
  1074. * Description:
  1075. * Sends or queues a chunk of data to the virtual channel
  1076. *
  1077. * Parameters:
  1078. * hGlobMem - handle to a HGLOBAL
  1079. * uiBlockSize - size of the chunk
  1080. *
  1081. * Returns:
  1082. * TRUE on success
  1083. *
  1084. */
  1085. BOOL
  1086. CRDPSound::ChannelWrite(
  1087. LPVOID pData,
  1088. UINT32 uiBlockSize
  1089. )
  1090. {
  1091. BOOL rv = FALSE;
  1092. DWORD Handle = m_dwChannel;
  1093. UINT rc;
  1094. ASSERT(Handle != INVALID_CHANNELID);
  1095. ASSERT(m_ChannelEntries.pVirtualChannelWriteEx);
  1096. // parameters check
  1097. //
  1098. if (INVALID_CHANNELID == Handle)
  1099. {
  1100. TRC(ERR, _T("ChannelWrite: invalid handle\n"));
  1101. goto exitpt;
  1102. }
  1103. TRC(ALV, _T("Sending ptr=%p, Size=%d\n"), pData, uiBlockSize);
  1104. rc = m_ChannelEntries.pVirtualChannelWriteEx(
  1105. m_pInitHandle,
  1106. Handle,
  1107. pData,
  1108. uiBlockSize,
  1109. pData);
  1110. if (rc != CHANNEL_RC_OK)
  1111. {
  1112. TRC(INF, _T("VirtualChannelWrite failed rv=%d"), rc);
  1113. goto exitpt;
  1114. }
  1115. rv = TRUE;
  1116. exitpt:
  1117. if (!rv)
  1118. {
  1119. TRC(ERR, _T("ChannelWrite: Failed to send data\n"));
  1120. }
  1121. return rv;
  1122. }
  1123. /*
  1124. * Function:
  1125. * vcwaveCallbacl
  1126. *
  1127. * Description:
  1128. * WaveOut callbacks
  1129. *
  1130. */
  1131. VOID
  1132. CRDPSound::vcwaveCallback(
  1133. HWAVEOUT hWave,
  1134. UINT uMsg,
  1135. LPWAVEHDR lpWaveHdr
  1136. )
  1137. {
  1138. switch (uMsg)
  1139. {
  1140. case WOM_OPEN:
  1141. TRC(ALV, _T("vcwaveCallback: WOM_OPEN\n"));
  1142. break;
  1143. case WOM_CLOSE:
  1144. TRC(ALV, _T("vcwaveCallback: WOM_CLOSE\n"));
  1145. break;
  1146. case WOM_DONE:
  1147. {
  1148. SNDWAVECONFIRM WaveConfirm;
  1149. ASSERT( 0 != ( lpWaveHdr->dwFlags & WHDR_PREPARED ));
  1150. if ( 0 == ( lpWaveHdr->dwFlags & WHDR_PREPARED ))
  1151. {
  1152. TRC( ERR, _T("vcwaveCallback: buffer already unprepared\n") );
  1153. } else if ( m_hWave != hWave )
  1154. {
  1155. TRC( ERR, _T("vcwaveCallback: can't unprepare header, beacuse ")
  1156. _T("the stream is already closed\n"));
  1157. } else {
  1158. MMRESULT mmres;
  1159. mmres = waveOutUnprepareHeader(
  1160. hWave,
  1161. lpWaveHdr,
  1162. sizeof(*lpWaveHdr)
  1163. );
  1164. ASSERT( mmres == MMSYSERR_NOERROR );
  1165. #if DBG
  1166. m_lPrepdBlocks --;
  1167. #endif // DBG
  1168. }
  1169. if (lpWaveHdr)
  1170. {
  1171. DWORD dw = PtrToLong((PVOID)lpWaveHdr->dwUser);
  1172. WaveConfirm.cConfirmedBlockNo = (BYTE)(dw >> 16);
  1173. //
  1174. // adjust completly the time stamp
  1175. // see vcwaveWrite
  1176. //
  1177. WaveConfirm.wTimeStamp = (WORD)
  1178. ((dw & 0xffff) + GetTickCount());
  1179. #if _STAT_DBG
  1180. TRC(INF, _T("blockno=%d, adjusted time stamp=%x\n"),
  1181. WaveConfirm.cConfirmedBlockNo, WaveConfirm.wTimeStamp);
  1182. #endif
  1183. TRC(ALV, _T("vcwaveCallback: WOM_DONE, block no %d\n"),
  1184. WaveConfirm.cConfirmedBlockNo);
  1185. if (lpWaveHdr->lpData)
  1186. {
  1187. #ifdef OS_WINCE
  1188. lpWaveHdr->lpData = (char *)UnMapPtr(lpWaveHdr->lpData);
  1189. if (lpWaveHdr->lpData)
  1190. #endif
  1191. free(lpWaveHdr->lpData);
  1192. }
  1193. else
  1194. TRC(ERR, _T("vcwaveCallback: WOM_DONE: lpWaveHdr->lpData is NULL\n"));
  1195. free(lpWaveHdr);
  1196. } else
  1197. TRC(ERR, _T("vcwaveCallback: WOM_DONE: lpWaveHdr is NULL\n"));
  1198. // Send the confirmation
  1199. //
  1200. WaveConfirm.Prolog.Type = SNDC_WAVECONFIRM;
  1201. WaveConfirm.Prolog.BodySize = sizeof(WaveConfirm) -
  1202. sizeof(WaveConfirm.Prolog);
  1203. if ( 0 != m_ulRemoteDGramAddress )
  1204. DGramSend( &WaveConfirm, sizeof(WaveConfirm));
  1205. else
  1206. ChannelWriteNCopy( &WaveConfirm, sizeof( WaveConfirm ));
  1207. m_dwWavesPlaying --;
  1208. ASSERT( -1 != m_dwWavesPlaying );
  1209. if ( 0 == m_dwWavesPlaying && NULL != m_pFirstWave )
  1210. {
  1211. TRC(INF, _T("vcwaveCallback: WOM_DONE: attempt to resample\n"));
  1212. PostMessage( m_hMsgWindow, WM_RESAMPLE, 0, 0 );
  1213. }
  1214. }
  1215. break;
  1216. }
  1217. }
  1218. /*
  1219. * Function:
  1220. * vcwaveGetDevCaps
  1221. *
  1222. * Description:
  1223. * Queries for device capabilities
  1224. *
  1225. */
  1226. VOID
  1227. CRDPSound::vcwaveGetDevCaps(
  1228. PSNDFORMATMSG pFmtMsg
  1229. )
  1230. {
  1231. WAVEFORMATEX Format;
  1232. MMRESULT mmres;
  1233. DWORD dw;
  1234. ASSERT( NULL != pFmtMsg );
  1235. pFmtMsg->dwFlags = 0;
  1236. pFmtMsg->dwVolume = 0;
  1237. pFmtMsg->dwPitch = 0;
  1238. pFmtMsg->wDGramPort = 0;
  1239. Format.wFormatTag = WAVE_FORMAT_PCM;
  1240. Format.nChannels = TSSND_NATIVE_CHANNELS;
  1241. Format.nSamplesPerSec = TSSND_NATIVE_SAMPLERATE;
  1242. Format.nAvgBytesPerSec = TSSND_NATIVE_AVGBYTESPERSEC;
  1243. Format.nBlockAlign = TSSND_NATIVE_BLOCKALIGN;
  1244. Format.wBitsPerSample = TSSND_NATIVE_BITSPERSAMPLE;
  1245. Format.cbSize = 0;
  1246. if (!vcwaveOpen(&Format))
  1247. {
  1248. TRC(ERR, _T("vcwaveGetDevCaps: can't open device\n"));
  1249. goto exitpt;
  1250. }
  1251. ASSERT( NULL != m_hWave );
  1252. pFmtMsg->dwFlags = TSSNDCAPS_ALIVE;
  1253. pFmtMsg->wDGramPort = DGramGetLocalPort();
  1254. mmres = waveOutGetVolume(m_hWave, &dw);
  1255. if (MMSYSERR_NOERROR == mmres)
  1256. {
  1257. pFmtMsg->dwFlags |= TSSNDCAPS_VOLUME;
  1258. pFmtMsg->dwVolume = dw;
  1259. }
  1260. else
  1261. TRC(ERR, _T("vcwaveGetDevCaps: device doesn't support volume control\n"));
  1262. mmres = waveOutGetPitch(m_hWave, &dw);
  1263. if (MMSYSERR_NOERROR == mmres)
  1264. {
  1265. pFmtMsg->dwFlags |= TSSNDCAPS_PITCH;
  1266. pFmtMsg->dwPitch = dw;
  1267. }
  1268. else
  1269. TRC(INF, _T("vcwaveGetDevCaps: device doesn't support pitch control\n"));
  1270. vcwaveClose();
  1271. exitpt:
  1272. ;
  1273. }
  1274. /*
  1275. * Function:
  1276. * vcwaveChooseSoundFormat
  1277. *
  1278. * Description:
  1279. * Queries the local device for different formats
  1280. *
  1281. */
  1282. BOOL
  1283. CRDPSound::vcwaveChooseSoundFormat(
  1284. DWORD dwNumberOfFormats,
  1285. PSNDFORMATITEM pSndFormats,
  1286. PSNDFORMATITEM *ppSndFormatFound,
  1287. DWORD *pdwListSize,
  1288. DWORD *pdwNumFormats
  1289. )
  1290. {
  1291. PSNDFORMATITEM pSndFormat;
  1292. //
  1293. // query the waveout device with different wave formats
  1294. // returns the list of successfull formats in pSndFormatFound
  1295. // FALSE in any other case
  1296. // the caller takes responsibility for freeing the data in
  1297. // *ppSndFormatFound
  1298. //
  1299. BOOL rv = FALSE;
  1300. DWORD i;
  1301. PSNDFORMATITEM pSndFormatFound = NULL;
  1302. LPSTR pFmtCopy;
  1303. DWORD dwListSize = 0;
  1304. DWORD dwNumFormats = 0;
  1305. ASSERT( NULL != pSndFormats );
  1306. ASSERT( NULL != ppSndFormatFound );
  1307. ASSERT( NULL != pdwListSize );
  1308. ASSERT( NULL != pdwNumFormats );
  1309. for ( i = 0, pSndFormat = pSndFormats;
  1310. i < dwNumberOfFormats;
  1311. i++, pSndFormat = (PSNDFORMATITEM)
  1312. (((LPSTR)pSndFormat) + sizeof( *pSndFormat ) + pSndFormat->cbSize)
  1313. )
  1314. {
  1315. MMRESULT mmres;
  1316. PSNDFORMATITEM pFmtToOpen = pSndFormat;
  1317. PSNDFORMATITEM pFixedFormat = NULL;
  1318. //
  1319. // fix the format for WMA audio
  1320. // copy and modify it in another structure, so we don't disrupt
  1321. // the original
  1322. //
  1323. if ( WAVE_FORMAT_WMAUDIO2 == pSndFormat->wFormatTag )
  1324. {
  1325. DWORD dwTotalSize = sizeof( WMAUDIO2WAVEFORMAT ) -
  1326. sizeof( WAVEFORMATEX ) + sizeof( WMAUDIO_DEC_KEY );
  1327. ASSERT( pSndFormat->cbSize == dwTotalSize );
  1328. if ( pSndFormat->cbSize == dwTotalSize )
  1329. {
  1330. pFixedFormat = (PSNDFORMATITEM)malloc( sizeof( WMAUDIO2WAVEFORMAT ) +
  1331. sizeof( WMAUDIO_DEC_KEY ));
  1332. if ( NULL != pFixedFormat )
  1333. {
  1334. memcpy( pFixedFormat, pSndFormat, sizeof( pSndFormat ) + pSndFormat->cbSize );
  1335. strncpy((CHAR *)(((WMAUDIO2WAVEFORMAT *) pFixedFormat) + 1),
  1336. WMAUDIO_DEC_KEY, sizeof( WMAUDIO_DEC_KEY ));
  1337. pFmtToOpen = pFixedFormat;
  1338. }
  1339. }
  1340. }
  1341. mmres = waveOutOpen(
  1342. NULL,
  1343. WAVE_MAPPER,
  1344. (LPWAVEFORMATEX)pFmtToOpen,
  1345. 0,
  1346. 0,
  1347. WAVE_FORMAT_QUERY
  1348. );
  1349. if ( NULL != pFixedFormat )
  1350. {
  1351. free( pFixedFormat );
  1352. }
  1353. TRC(ALV, _T("FormatTag - %d\n"), pSndFormat->wFormatTag);
  1354. TRC(ALV, _T("Channels - %d\n"), pSndFormat->nChannels);
  1355. TRC(ALV, _T("SamplesPerSec - %d\n"), pSndFormat->nSamplesPerSec);
  1356. TRC(ALV, _T("AvgBytesPerSec - %d\n"), pSndFormat->nAvgBytesPerSec);
  1357. TRC(ALV, _T("BlockAlign - %d\n"), pSndFormat->nBlockAlign);
  1358. TRC(ALV, _T("BitsPerSample - %d\n"), pSndFormat->wBitsPerSample);
  1359. TRC(ALV, _T("cbSize - %d\n"), pSndFormat->cbSize);
  1360. if ( MMSYSERR_NOERROR == mmres )
  1361. {
  1362. //
  1363. // this format is supported
  1364. //
  1365. TRC(ALV, _T("vcwaveChooseSoundFormat: format found\n"));
  1366. dwListSize += sizeof( *pSndFormat ) + pSndFormat->cbSize;
  1367. dwNumFormats ++;
  1368. } else {
  1369. //
  1370. // if not supported,
  1371. // zero it's AvgBytesPerSec member
  1372. //
  1373. TRC(INF, _T("vcwaveChooseSoundFormat: format not supported\n"));
  1374. pSndFormat->nAvgBytesPerSec = 0;
  1375. }
  1376. }
  1377. if ( 0 == dwListSize )
  1378. {
  1379. TRC(WRN, _T("vcwaveChooseSoundFormat: no formats found\n"));
  1380. goto exitpt;
  1381. }
  1382. pSndFormatFound = (PSNDFORMATITEM)malloc( dwListSize );
  1383. if ( NULL == pSndFormatFound )
  1384. {
  1385. TRC( ERR, _T("vcwaveChooseSoundFormat: can't allocate %d bytes\n"),
  1386. dwListSize );
  1387. dwListSize = 0;
  1388. dwNumFormats = 0;
  1389. goto exitpt;
  1390. }
  1391. //
  1392. // copy the list of supported formats
  1393. //
  1394. for ( i = 0, pSndFormat = pSndFormats, pFmtCopy = (LPSTR)pSndFormatFound;
  1395. i < dwNumberOfFormats;
  1396. i++, pSndFormat = (PSNDFORMATITEM)
  1397. (((LPSTR)pSndFormat) + sizeof( *pSndFormat ) + pSndFormat->cbSize)
  1398. )
  1399. {
  1400. if ( 0 != pSndFormat->nAvgBytesPerSec )
  1401. {
  1402. memcpy( pFmtCopy,
  1403. pSndFormat,
  1404. sizeof( *pSndFormat ) + pSndFormat->cbSize);
  1405. pFmtCopy += sizeof( *pSndFormat ) + pSndFormat->cbSize;
  1406. }
  1407. }
  1408. rv = TRUE;
  1409. exitpt:
  1410. *ppSndFormatFound = pSndFormatFound;
  1411. *pdwListSize = dwListSize;
  1412. *pdwNumFormats = dwNumFormats;
  1413. return rv;
  1414. }
  1415. /*
  1416. * Function:
  1417. * vcwaveCleanSoundForamt
  1418. *
  1419. * Description:
  1420. * Cleans the list of negotiated formats
  1421. *
  1422. */
  1423. VOID
  1424. CRDPSound::vcwaveCleanSoundFormats(
  1425. VOID
  1426. )
  1427. {
  1428. DWORD i;
  1429. if ( NULL == m_ppFormats )
  1430. goto exitpt;
  1431. //
  1432. // dispose the allocated structures
  1433. //
  1434. for (i = 0; i < m_dwNumFormats; i++)
  1435. {
  1436. if ( NULL != m_ppFormats[i] )
  1437. free( m_ppFormats[i] );
  1438. }
  1439. free( m_ppFormats );
  1440. m_ppFormats = NULL;
  1441. m_dwNumFormats = 0;
  1442. exitpt:
  1443. ;
  1444. }
  1445. /*
  1446. * Function:
  1447. * vcwaveSafeSoundFormats
  1448. *
  1449. * Description:
  1450. * Saves the list of negotiated formats
  1451. *
  1452. */
  1453. BOOL
  1454. CRDPSound::vcwaveSaveSoundFormats(
  1455. PSNDFORMATITEM pSndFormats,
  1456. DWORD dwNumFormats
  1457. )
  1458. {
  1459. BOOL rv = FALSE;
  1460. DWORD i;
  1461. DWORD dwAllocSize;
  1462. LPSTR p;
  1463. ASSERT( NULL != pSndFormats );
  1464. ASSERT( 0 != dwNumFormats );
  1465. if ( NULL != m_ppFormats )
  1466. {
  1467. vcwaveCleanSoundFormats();
  1468. }
  1469. ASSERT( NULL == m_ppFormats );
  1470. ASSERT( 0 == m_dwNumFormats );
  1471. dwAllocSize = sizeof( PSNDFORMATITEM ) * dwNumFormats;
  1472. m_ppFormats = (PSNDFORMATITEM *)malloc( dwAllocSize );
  1473. if ( NULL == m_ppFormats )
  1474. {
  1475. TRC(ERR, _T("Failed to allocate %d bytes\n"),
  1476. dwAllocSize );
  1477. goto exitpt;
  1478. }
  1479. memset( m_ppFormats, 0, dwAllocSize );
  1480. for (i = 0, p = (LPSTR)pSndFormats;
  1481. i < dwNumFormats;
  1482. i++, p += sizeof(SNDFORMATITEM) + ((PSNDFORMATITEM)p)->cbSize)
  1483. {
  1484. PSNDFORMATITEM pFmt;
  1485. pFmt = (PSNDFORMATITEM) p;
  1486. dwAllocSize = sizeof(SNDFORMATITEM) + pFmt->cbSize;
  1487. m_ppFormats[i] = (PSNDFORMATITEM)malloc( dwAllocSize );
  1488. if ( NULL == (PVOID)m_ppFormats[i] )
  1489. {
  1490. TRC(ERR, _T("Failed to allocate %d bytes\n"),
  1491. dwAllocSize );
  1492. goto exitpt;
  1493. }
  1494. //
  1495. // copy the format
  1496. //
  1497. memcpy( m_ppFormats[i], pFmt, dwAllocSize );
  1498. }
  1499. m_dwNumFormats = dwNumFormats;
  1500. rv = TRUE;
  1501. exitpt:
  1502. if (!rv && NULL != m_ppFormats)
  1503. {
  1504. // dispose the allocated structures
  1505. //
  1506. for (i = 0; i < dwNumFormats; i++)
  1507. {
  1508. if ( NULL != m_ppFormats[i] )
  1509. free( m_ppFormats[i] );
  1510. }
  1511. free( m_ppFormats );
  1512. m_ppFormats = NULL;
  1513. m_dwNumFormats = 0;
  1514. }
  1515. return rv;
  1516. }
  1517. /*
  1518. * Function:
  1519. * vcwaveClose
  1520. *
  1521. * Description:
  1522. * Closes the local device
  1523. *
  1524. */
  1525. VOID
  1526. CRDPSound::vcwaveClose(
  1527. VOID
  1528. )
  1529. {
  1530. MSG msg;
  1531. UINT_PTR idTimer;
  1532. if ( NULL == m_hWave )
  1533. goto exitpt;
  1534. //
  1535. // process all MM_WOM_DONE messages
  1536. //
  1537. ASSERT( NULL != m_hMsgWindow );
  1538. //
  1539. // start a timeout timer
  1540. //
  1541. idTimer = SetTimer( m_hMsgWindow, 1, WAVE_CLOSE_TIMEOUT, NULL );
  1542. while( 0 != m_dwWavesPlaying &&
  1543. GetMessage( &msg, m_hMsgWindow, 0, 0 ))
  1544. {
  1545. if ( WM_TIMER == msg.message && msg.wParam == idTimer )
  1546. {
  1547. //
  1548. // cancel outstanding io
  1549. //
  1550. TRC( WRN, _T("TIMEDOUT waiting for the playing to complete. Resetting\n" ));
  1551. waveOutReset( m_hWave );
  1552. }
  1553. DispatchMessage(&msg);
  1554. }
  1555. if ( 0 != idTimer )
  1556. {
  1557. KillTimer( m_hMsgWindow, idTimer );
  1558. }
  1559. waveOutClose(m_hWave);
  1560. #ifdef DBG
  1561. if ( 0 != InterlockedDecrement(&m_lTimesWaveOutOpened))
  1562. {
  1563. TRC(FATAL, _T("Device was closed too many times\n"));
  1564. ASSERT(0);
  1565. }
  1566. ASSERT( 0 == m_dwWavesPlaying );
  1567. ASSERT( 0 == m_lPrepdBlocks );
  1568. #endif
  1569. m_hWave = NULL;
  1570. exitpt:
  1571. ;
  1572. }
  1573. /*
  1574. * Function:
  1575. * vcwaveOpen
  1576. *
  1577. * Description:
  1578. * Opens the device in given format
  1579. *
  1580. */
  1581. BOOL
  1582. CRDPSound::vcwaveOpen(
  1583. LPWAVEFORMATEX pFormat
  1584. )
  1585. {
  1586. BOOL rv = FALSE;
  1587. MMRESULT mmres;
  1588. if (m_hWave)
  1589. {
  1590. TRC(WRN, _T("vcwaveOpen: device is already opened. Reopening\n"));
  1591. waveOutReset(m_hWave);
  1592. vcwaveClose();
  1593. }
  1594. if (INVALID_SOCKET == m_hDGramSocket)
  1595. {
  1596. TRC(ERR, _T("vcwaveOpen: no datagram connection, falling to VC\n"));
  1597. }
  1598. // 11.025 kHz, 8 bit, mono
  1599. if (NULL == m_hMsgWindow && !CreateMsgWindow(m_hInst))
  1600. goto exitpt;
  1601. //
  1602. // fix the format for WMA audio
  1603. //
  1604. if ( WAVE_FORMAT_WMAUDIO2 == pFormat->wFormatTag )
  1605. {
  1606. DWORD dwTotalSize = sizeof( WMAUDIO2WAVEFORMAT ) -
  1607. sizeof( WAVEFORMATEX ) + sizeof( WMAUDIO_DEC_KEY );
  1608. ASSERT( pFormat->cbSize == dwTotalSize );
  1609. if ( pFormat->cbSize == dwTotalSize )
  1610. {
  1611. strncpy((CHAR *)(((WMAUDIO2WAVEFORMAT *) pFormat) + 1),
  1612. WMAUDIO_DEC_KEY, sizeof( WMAUDIO_DEC_KEY ));
  1613. }
  1614. }
  1615. mmres = waveOutOpen(
  1616. &m_hWave,
  1617. WAVE_MAPPER,
  1618. pFormat,
  1619. (DWORD_PTR)m_hMsgWindow,
  1620. 0, // CallbackInstance
  1621. CALLBACK_WINDOW
  1622. );
  1623. if (MMSYSERR_NOERROR != mmres)
  1624. {
  1625. TRC(WRN, _T("vcwaveOpen: failed to open WaveOut device: MMRESULT=%d\n"),
  1626. mmres);
  1627. goto exitpt;
  1628. }
  1629. #ifdef OS_WINCE
  1630. TRC(ALV, _T("waveOutOpen succeeded with following format %d\n"), pFormat->wFormatTag);
  1631. TRC(ALV, _T("FormatTag - %d\n"), pFormat->wFormatTag);
  1632. TRC(ALV, _T("Channels - %d\n"), pFormat->nChannels);
  1633. TRC(ALV, _T("SamplesPerSec - %d\n"), pFormat->nSamplesPerSec);
  1634. TRC(ALV, _T("AvgBytesPerSec - %d\n"), pFormat->nAvgBytesPerSec);
  1635. TRC(ALV, _T("BlockAlign - %d\n"), pFormat->nBlockAlign);
  1636. TRC(ALV, _T("BitsPerSample - %d\n"), pFormat->wBitsPerSample);
  1637. TRC(ALV, _T("cbSize - %d\n"), pFormat->cbSize);
  1638. #endif
  1639. #ifdef DBG
  1640. // Win95 InterlockedIncrement() difference.
  1641. InterlockedIncrement(&m_lTimesWaveOutOpened);
  1642. if ( 1 != m_lTimesWaveOutOpened )
  1643. {
  1644. TRC(FATAL, _T("Device was opened %d times\n"),
  1645. m_lTimesWaveOutOpened);
  1646. ASSERT(0);
  1647. }
  1648. #endif
  1649. rv = TRUE;
  1650. exitpt:
  1651. return rv;
  1652. }
  1653. /*
  1654. * Function:
  1655. * vcwaveFreeAllWaves
  1656. *
  1657. * Description:
  1658. * Frees all queued data
  1659. *
  1660. */
  1661. VOID
  1662. CRDPSound::vcwaveFreeAllWaves(
  1663. VOID
  1664. )
  1665. {
  1666. while ( NULL != m_pFirstWave )
  1667. {
  1668. LPWAVEHDR lpNext = m_pFirstWave->lpNext;
  1669. free( m_pFirstWave->lpData );
  1670. free( m_pFirstWave );
  1671. m_pFirstWave = lpNext;
  1672. }
  1673. m_pFirstWave = m_pLastWave = NULL;
  1674. }
  1675. /*
  1676. * Function:
  1677. * vcwaveOutWrite
  1678. *
  1679. * Description:
  1680. * Writes a data to the output sound device
  1681. *
  1682. */
  1683. MMRESULT
  1684. CRDPSound::vcwaveOutWrite(
  1685. LPWAVEHDR lpWaveHdr
  1686. )
  1687. {
  1688. MMRESULT mmres;
  1689. mmres = waveOutPrepareHeader(
  1690. m_hWave,
  1691. lpWaveHdr,
  1692. sizeof(*lpWaveHdr)
  1693. );
  1694. if (MMSYSERR_NOERROR != mmres)
  1695. {
  1696. TRC(WRN, _T("vcwaveOpen: failed to prepare buffer: MMRESULT=%d\n"),
  1697. mmres);
  1698. goto exitpt;
  1699. }
  1700. m_dwWavesPlaying++;
  1701. #if DBG
  1702. m_lPrepdBlocks ++;
  1703. #endif
  1704. mmres = waveOutWrite(
  1705. m_hWave,
  1706. lpWaveHdr,
  1707. sizeof(*lpWaveHdr)
  1708. );
  1709. if (MMSYSERR_NOERROR != mmres)
  1710. {
  1711. TRC(WRN, _T("vcwaveOpen: failed to write in WaveOut device: MMRESULT=%d\n"),
  1712. mmres);
  1713. waveOutUnprepareHeader(
  1714. m_hWave,
  1715. lpWaveHdr,
  1716. sizeof(*lpWaveHdr)
  1717. );
  1718. m_dwWavesPlaying --;
  1719. #if DBG
  1720. m_lPrepdBlocks --;
  1721. #endif
  1722. goto exitpt;
  1723. }
  1724. exitpt:
  1725. return mmres;
  1726. }
  1727. /*
  1728. * Function:
  1729. * vcwaveWrite
  1730. *
  1731. * Description:
  1732. * If the format id is not changes calls vcwaveOutWrite
  1733. * otherwise queues the data for later
  1734. *
  1735. */
  1736. BOOL
  1737. CRDPSound::vcwaveWrite(
  1738. BYTE cBlockNo,
  1739. DWORD dwFormatNo,
  1740. DWORD dwTimeStamp,
  1741. DWORD dwWaveDataLen,
  1742. LPVOID pData
  1743. )
  1744. {
  1745. BOOL rv = FALSE;
  1746. LPVOID lpWaveData = NULL;
  1747. LPWAVEHDR lpWaveHdr = NULL;
  1748. MMRESULT mmres;
  1749. BOOL bDontPlay = FALSE;
  1750. //
  1751. // put the stamp here to remove the delay of opening the device
  1752. //
  1753. DWORD dwStartStamp = GetTickCount() & 0xffff;
  1754. if ( NULL != m_hWave &&
  1755. m_dwCurrentFormat != dwFormatNo )
  1756. {
  1757. bDontPlay = TRUE;
  1758. }
  1759. if (NULL == m_hWave)
  1760. {
  1761. TRC(ALV, _T("wcwaveWrite: attempting to open the device\n"));
  1762. if (dwFormatNo >= m_dwNumFormats)
  1763. {
  1764. TRC(FATAL, _T("Invalid format no: %d\n"),
  1765. dwFormatNo);
  1766. goto exitpt;
  1767. }
  1768. if ( NULL == m_ppFormats )
  1769. {
  1770. TRC(FATAL, _T("No formats available(NULL)\n"));
  1771. goto exitpt;
  1772. }
  1773. if ( !vcwaveOpen( (LPWAVEFORMATEX)m_ppFormats[dwFormatNo] ))
  1774. TRC(ERR, _T("Can't open the device\n"));
  1775. m_dwCurrentFormat = dwFormatNo;
  1776. }
  1777. if ((BYTE)( m_cLastReceivedBlock - cBlockNo ) < TSSND_BLOCKSONTHENET)
  1778. {
  1779. TRC(WRN, _T("wcwaveWrite: received old block, ")
  1780. _T("the last one is %d, this one is %d. Discarding\n"),
  1781. m_cLastReceivedBlock,
  1782. cBlockNo);
  1783. goto exitpt;
  1784. } else
  1785. m_cLastReceivedBlock = cBlockNo;
  1786. lpWaveData = malloc(dwWaveDataLen);
  1787. if (!lpWaveData)
  1788. {
  1789. TRC(ERR, _T("vcwaveWrite: malloc failed to allocate %d bytes\n"),
  1790. dwWaveDataLen);
  1791. goto exitpt;
  1792. }
  1793. lpWaveHdr = (LPWAVEHDR)malloc(sizeof(*lpWaveHdr));
  1794. if (!lpWaveHdr)
  1795. {
  1796. TRC(ERR, _T("vcwaveWrite: malloc failed for %d bytes\n"),
  1797. sizeof(*lpWaveHdr));
  1798. goto exitpt;
  1799. }
  1800. memset(lpWaveHdr, 0, sizeof(*lpWaveHdr));
  1801. memcpy(lpWaveData, pData, dwWaveDataLen);
  1802. lpWaveHdr->lpData = (LPSTR)lpWaveData;
  1803. lpWaveHdr->dwBufferLength = dwWaveDataLen;
  1804. lpWaveHdr->dwFlags = 0;
  1805. lpWaveHdr->dwLoops = 0;
  1806. //
  1807. // here, we'll do a little magic with the time stamp
  1808. // in order to exclude the time when time packet is in the wave queue
  1809. // we'll subtract the current time now and add the time when
  1810. // confirmation is to be send
  1811. //
  1812. #if _STAT_DBG
  1813. TRC(INF, _T("blockno=%d, time stamp=%x\n"),
  1814. cBlockNo, dwTimeStamp );
  1815. #endif
  1816. lpWaveHdr->dwUser = (cBlockNo << 16) +
  1817. ((dwTimeStamp - dwStartStamp ) & 0xffff);
  1818. if ( bDontPlay )
  1819. {
  1820. //
  1821. // format change
  1822. // add this wave to the list
  1823. //
  1824. lpWaveHdr->reserved = dwFormatNo;
  1825. lpWaveHdr->lpNext = NULL;
  1826. if ( NULL != m_pLastWave )
  1827. m_pLastWave->lpNext = lpWaveHdr;
  1828. else
  1829. m_pFirstWave = lpWaveHdr;
  1830. m_pLastWave = lpWaveHdr;
  1831. ASSERT( NULL != lpWaveHdr->lpData );
  1832. TRC(INF, _T("vcwaveWrite: posting WM_RESAMPLE\n"));
  1833. PostMessage( m_hMsgWindow, WM_RESAMPLE, 0, 0 );
  1834. goto leavept;
  1835. }
  1836. mmres = vcwaveOutWrite( lpWaveHdr );
  1837. if (MMSYSERR_NOERROR != mmres)
  1838. {
  1839. TRC(WRN, _T("vcwaveOpen: failed to play a buffer: MMRESULT=%d\n"),
  1840. mmres);
  1841. goto exitpt;
  1842. }
  1843. leavept:
  1844. rv = TRUE;
  1845. exitpt:
  1846. if (!rv)
  1847. {
  1848. if (lpWaveData)
  1849. free(lpWaveData);
  1850. if (lpWaveHdr)
  1851. free(lpWaveHdr);
  1852. }
  1853. return rv;
  1854. }
  1855. /*
  1856. * Function:
  1857. * DGramInit
  1858. *
  1859. * Description:
  1860. * Init our UDP socket
  1861. *
  1862. */
  1863. BOOL
  1864. CRDPSound::DGramInit(
  1865. VOID
  1866. )
  1867. {
  1868. BOOL rv = FALSE;
  1869. #ifndef OS_WINCE
  1870. INT optval;
  1871. #endif
  1872. INT rc;
  1873. struct sockaddr_in sin;
  1874. ASSERT(INVALID_SOCKET == m_hDGramSocket);
  1875. m_hDGramSocket = socket(AF_INET, SOCK_DGRAM, 0);
  1876. if (INVALID_SOCKET == m_hDGramSocket)
  1877. {
  1878. TRC(ERR, _T("DGramInit: can't create dgram socket: %d\n"),
  1879. WSAGetLastError());
  1880. goto exitpt;
  1881. }
  1882. // bind the socket to any port/address
  1883. //
  1884. sin.sin_family = PF_INET;
  1885. sin.sin_port = htons(0); // any port between 1024 and 50000
  1886. sin.sin_addr.s_addr = INADDR_ANY;
  1887. rc = bind(m_hDGramSocket, (struct sockaddr *)(&sin), sizeof(sin));
  1888. if (SOCKET_ERROR == rc)
  1889. {
  1890. TRC(ERR, _T("DGramInit: can't bind the socket: %d\n"),
  1891. WSAGetLastError());
  1892. goto exitpt;
  1893. }
  1894. #ifndef OS_WINCE
  1895. //
  1896. // assign an appropriate buffer length
  1897. //
  1898. optval = TSSND_BLOCKSONTHENET * (sizeof(SNDWAVE) + TSSND_BLOCKSIZE);
  1899. rc = setsockopt(m_hDGramSocket,
  1900. SOL_SOCKET,
  1901. SO_RCVBUF,
  1902. (LPSTR)&optval,
  1903. sizeof(optval));
  1904. if (SOCKET_ERROR == rc)
  1905. {
  1906. TRC(ERR, _T("DGramInit: setsockopt failed: %d\n"),
  1907. WSAGetLastError());
  1908. goto exitpt;
  1909. }
  1910. #endif
  1911. // select the socket on the message window
  1912. //
  1913. if (NULL != m_hMsgWindow &&
  1914. SOCKET_ERROR ==
  1915. WSAAsyncSelect(m_hDGramSocket, m_hMsgWindow,
  1916. WM_WSOCK, FD_READ))
  1917. {
  1918. TRC(ERR, _T("DGramInit: WSAAsyncSelect failed: %d\n"),
  1919. WSAGetLastError());
  1920. goto exitpt;
  1921. }
  1922. rv = TRUE;
  1923. exitpt:
  1924. if (!rv && INVALID_SOCKET != m_hDGramSocket)
  1925. {
  1926. closesocket(m_hDGramSocket);
  1927. m_hDGramSocket = INVALID_SOCKET;
  1928. }
  1929. return rv;
  1930. }
  1931. /*
  1932. * Function:
  1933. * DGramDone
  1934. *
  1935. * Description:
  1936. * Destroy our UDP socket
  1937. *
  1938. */
  1939. VOID
  1940. CRDPSound::DGramDone(
  1941. VOID
  1942. )
  1943. {
  1944. if (INVALID_SOCKET != m_hDGramSocket)
  1945. {
  1946. closesocket(m_hDGramSocket);
  1947. m_hDGramSocket = INVALID_SOCKET;
  1948. }
  1949. }
  1950. /*
  1951. * Function:
  1952. * DGramGetLocalPort
  1953. *
  1954. * Description:
  1955. * Retreives the local UDP port
  1956. *
  1957. */
  1958. u_short
  1959. CRDPSound::DGramGetLocalPort(
  1960. VOID
  1961. )
  1962. {
  1963. u_short rv = 0;
  1964. struct sockaddr_in sin;
  1965. INT rc;
  1966. INT nSinSize;
  1967. if (INVALID_SOCKET == m_hDGramSocket)
  1968. {
  1969. TRC(ERR, _T("DGramGetLocalPort: invalid socket\n"));
  1970. goto exitpt;
  1971. }
  1972. nSinSize = sizeof(sin);
  1973. rc = getsockname(m_hDGramSocket,
  1974. (struct sockaddr *)&sin,
  1975. &nSinSize);
  1976. if (SOCKET_ERROR == rc)
  1977. {
  1978. TRC(ERR, _T("DGramGetLocalPort: getsockname failed: %d\n"),
  1979. WSAGetLastError());
  1980. goto exitpt;
  1981. }
  1982. ASSERT(PF_INET == sin.sin_family);
  1983. rv = sin.sin_port;
  1984. exitpt:
  1985. return rv;
  1986. }
  1987. /*
  1988. * Function:
  1989. * DGramSend
  1990. *
  1991. * Description:
  1992. * Send an UDP packet
  1993. *
  1994. */
  1995. BOOL
  1996. CRDPSound::DGramSend(
  1997. LPVOID pData,
  1998. DWORD dwSize
  1999. )
  2000. {
  2001. INT rc = SOCKET_ERROR;
  2002. struct sockaddr_in sin;
  2003. ASSERT( 0 != m_dwRemoteDGramPort );
  2004. ASSERT( 0 != m_ulRemoteDGramAddress );
  2005. if ( INVALID_SOCKET == m_hDGramSocket )
  2006. {
  2007. TRC(ERR, _T("DGramSend: invalid socket handle\n"));
  2008. goto exitpt;
  2009. }
  2010. sin.sin_family = PF_INET;
  2011. sin.sin_port = (u_short)m_dwRemoteDGramPort;
  2012. sin.sin_addr.s_addr = m_ulRemoteDGramAddress;
  2013. rc = sendto(
  2014. m_hDGramSocket,
  2015. (LPSTR)pData,
  2016. dwSize,
  2017. 0,
  2018. (struct sockaddr *)&sin,
  2019. sizeof( sin )
  2020. );
  2021. if ( SOCKET_ERROR == rc )
  2022. {
  2023. TRC(WRN, _T("DGramSend: sendto failed=%d\n"),
  2024. WSAGetLastError());
  2025. }
  2026. exitpt:
  2027. return ( rc != SOCKET_ERROR );
  2028. }
  2029. /*
  2030. * Function:
  2031. * DGramRecvWave
  2032. *
  2033. * Description:
  2034. * Recieve data from UDP
  2035. *
  2036. */
  2037. BOOL
  2038. CRDPSound::DGramRecvWave(
  2039. PSNDWAVE pSndWave,
  2040. DWORD dwSize
  2041. )
  2042. {
  2043. BOOL rv = FALSE;
  2044. INT recvd;
  2045. struct sockaddr_in sin_from;
  2046. INT nSinFrom;
  2047. // parameters check
  2048. //
  2049. if (NULL == pSndWave)
  2050. {
  2051. TRC(ERR, _T("DGramRecvWave: pSndWave is NULL\n"));
  2052. goto exitpt;
  2053. }
  2054. if (dwSize <= sizeof(*pSndWave))
  2055. {
  2056. TRC(ERR, _T("DGramRecvWave: no enough space to get the wave\n"));
  2057. goto exitpt;
  2058. }
  2059. // receive the message
  2060. //
  2061. nSinFrom = sizeof( sin_from );
  2062. recvd = recvfrom(
  2063. m_hDGramSocket,
  2064. (LPSTR)pSndWave,
  2065. dwSize,
  2066. 0,
  2067. (struct sockaddr *)&sin_from,
  2068. &nSinFrom
  2069. );
  2070. if (recvd < sizeof(pSndWave->Prolog) || ((DWORD)recvd) > dwSize)
  2071. {
  2072. if (SOCKET_ERROR == recvd)
  2073. TRC(ERR, _T("WM_WSOCK: recvfrom failed: %d\n"),
  2074. WSAGetLastError());
  2075. else
  2076. TRC(WRN,
  2077. _T("WM_WSOCK: received %d bytes instead %d. Discarding\n"),
  2078. recvd, sizeof(pSndWave->Prolog));
  2079. goto exitpt;
  2080. }
  2081. ASSERT( PF_INET == sin_from.sin_family );
  2082. if ( PF_INET != sin_from.sin_family )
  2083. {
  2084. TRC(WRN, _T("WM_WSOCK: message from invalid protocol( %x )\n"),
  2085. sin_from.sin_family );
  2086. goto exitpt;
  2087. }
  2088. if ( sizeof( sin_from ) > nSinFrom )
  2089. {
  2090. TRC(WRN, _T("WM_WSOCK: from address invalid, len=%d\n"),
  2091. nSinFrom );
  2092. goto exitpt;
  2093. }
  2094. m_dwRemoteDGramPort = sin_from.sin_port;
  2095. m_ulRemoteDGramAddress = sin_from.sin_addr.s_addr;
  2096. //
  2097. // Check for line-training request
  2098. //
  2099. if (SNDC_TRAINING == pSndWave->Prolog.Type)
  2100. {
  2101. SNDTRAINING SndTraining;
  2102. PSNDTRAINING pRecvTraining;
  2103. TRC(ALV, _T("DGramRecvWave: training, sending a response\n"));
  2104. pRecvTraining = (PSNDTRAINING)pSndWave;
  2105. SndTraining.Prolog.Type = SNDC_TRAINING;
  2106. SndTraining.Prolog.BodySize = sizeof(SndTraining) -
  2107. sizeof(SndTraining.Prolog);
  2108. SndTraining.wTimeStamp = pRecvTraining->wTimeStamp;
  2109. SndTraining.wPackSize = pRecvTraining->wPackSize;
  2110. //
  2111. // send the response immediatly
  2112. //
  2113. DGramSend( &SndTraining, sizeof(SndTraining) );
  2114. goto exitpt;
  2115. }
  2116. if ( SNDC_UDPWAVE == pSndWave->Prolog.Type)
  2117. {
  2118. rv = ConstructFromDGramFrags(
  2119. (PSNDUDPWAVE)pSndWave,
  2120. recvd,
  2121. pSndWave,
  2122. dwSize
  2123. );
  2124. goto exitpt;
  2125. } else if ( SNDC_UDPWAVELAST == pSndWave->Prolog.Type)
  2126. {
  2127. rv = ConstructFromDGramLastFrag(
  2128. (PSNDUDPWAVELAST)pSndWave,
  2129. recvd,
  2130. pSndWave,
  2131. dwSize
  2132. );
  2133. goto exitpt;
  2134. }
  2135. if (SNDC_WAVEENCRYPT == pSndWave->Prolog.Type)
  2136. {
  2137. if ( !SL_Encrypt(
  2138. (PBYTE)(pSndWave + 1),
  2139. pSndWave->dwBlockNo,
  2140. pSndWave->Prolog.BodySize - sizeof(SNDWAVE) + sizeof(SNDPROLOG) ))
  2141. goto exitpt;
  2142. }
  2143. else if (SNDC_WAVE != pSndWave->Prolog.Type)
  2144. {
  2145. TRC(ERR, _T("DGramRecvWave: invalid message type: %d\n"),
  2146. pSndWave->Prolog.Type);
  2147. goto exitpt;
  2148. }
  2149. if ( recvd < sizeof(SNDPROLOG) ||
  2150. pSndWave->Prolog.BodySize + sizeof(SNDPROLOG) != (DWORD)recvd)
  2151. {
  2152. TRC(WRN,
  2153. _T("WM_WSOCK: received %d bytes instead %d. Discarding\n"),
  2154. recvd, pSndWave->Prolog.BodySize + sizeof(SNDPROLOG) );
  2155. goto exitpt;
  2156. }
  2157. TRC(ALV, _T("DGramRecvWave: block no: %d\n"),
  2158. pSndWave->cBlockNo);
  2159. rv = TRUE;
  2160. exitpt:
  2161. return rv;
  2162. }
  2163. BOOL
  2164. CRDPSound::ConstructFromDGramFrags(
  2165. PSNDUDPWAVE pWave,
  2166. DWORD dwSize,
  2167. PSNDWAVE pReady,
  2168. DWORD dwReadySize
  2169. )
  2170. {
  2171. BOOL rv = FALSE;
  2172. PBYTE pRecvdData;
  2173. DWORD dwFragNo;
  2174. DWORD dwEstimatedSize;
  2175. DWORD dwDataSize;
  2176. PFRAGSLOT pSlot;
  2177. if ( dwSize <= sizeof( *pWave ))
  2178. {
  2179. TRC( ERR, _T("ConstructFromDGramFrags: packet too small %d\n"),
  2180. dwSize );
  2181. goto exitpt;
  2182. }
  2183. pRecvdData = (PBYTE)(pWave + 1);
  2184. dwFragNo = pWave->cFragNo & (~RDPSND_FRAGNO_EXT);
  2185. dwDataSize = dwSize - sizeof( *pWave );
  2186. if ( pWave->cFragNo & RDPSND_FRAGNO_EXT )
  2187. {
  2188. dwFragNo <<= 8;
  2189. dwFragNo += *pRecvdData;
  2190. pRecvdData++;
  2191. dwDataSize--;
  2192. }
  2193. dwEstimatedSize = ( dwFragNo + 1 ) * dwDataSize;
  2194. if ( dwEstimatedSize >= MAX_UDP_SIZE )
  2195. {
  2196. TRC( ERR, _T("ConstructFromDGramFrags: estimated size >=64K (0x%x)\n"),
  2197. dwEstimatedSize );
  2198. goto exitpt;
  2199. }
  2200. if (!_FragSlotFind( &pSlot, pWave->cBlockNo, dwEstimatedSize ))
  2201. {
  2202. goto exitpt;
  2203. }
  2204. if ( 0 != pSlot->dwFragSize && pSlot->dwFragSize != dwDataSize )
  2205. {
  2206. TRC( ERR, _T("ConstructFromDGramFrags: received frag with different size: %d, expect %d\n"),
  2207. dwDataSize, pSlot->dwFragSize );
  2208. _FragSlotClear( pSlot );
  2209. goto exitpt;
  2210. }
  2211. memcpy( pSlot->pData + dwFragNo * dwDataSize, pRecvdData, dwDataSize );
  2212. pSlot->dwFragSize = dwDataSize;
  2213. pSlot->dwTotalSize += dwDataSize;
  2214. // TRC( INF, _T("Fragment received: block#=0x%x, frag#=0x%x, total=0x%x\n"),
  2215. // pWave->cBlockNo, dwFragNo, pSlot->dwTotalSize );
  2216. if ( pSlot->dwTotalSize != pSlot->dwExpectedTotalSize )
  2217. {
  2218. goto exitpt;
  2219. }
  2220. //
  2221. // wave is ready, convert
  2222. //
  2223. if (!_FragSlotToWave( pSlot, pReady, dwReadySize ))
  2224. {
  2225. goto exitpt;
  2226. }
  2227. rv = TRUE;
  2228. exitpt:
  2229. return rv;
  2230. }
  2231. BOOL
  2232. CRDPSound::ConstructFromDGramLastFrag(
  2233. PSNDUDPWAVELAST pLast,
  2234. DWORD dwSize,
  2235. PSNDWAVE pReady,
  2236. DWORD dwReadySize
  2237. )
  2238. {
  2239. BOOL rv = FALSE;
  2240. DWORD dwDataSize;
  2241. PFRAGSLOT pSlot;
  2242. if ( dwSize < sizeof( *pLast ))
  2243. {
  2244. TRC( ERR, _T("ConstructFromDGramLastFrag: too small packet (%d)\n"), dwSize );
  2245. }
  2246. if (!_FragSlotFind( &pSlot, pLast->cBlockNo, pLast->wTotalSize ))
  2247. {
  2248. TRC( WRN, _T("ConstructFromDGramLastFrag: Failed to find a slot for last fragment\n" ));
  2249. goto exitpt;
  2250. }
  2251. pSlot->dwExpectedTotalSize = pLast->wTotalSize;
  2252. pSlot->wTimeStamp = pLast->wTimeStamp;
  2253. pSlot->wFormatNo = pLast->wFormatNo;
  2254. pSlot->dwBlockNo = pLast->dwBlockNo;
  2255. dwDataSize = dwSize - sizeof( *pLast );
  2256. memcpy( pSlot->pData + pSlot->dwExpectedTotalSize - dwDataSize, pLast + 1, dwDataSize );
  2257. pSlot->dwTotalSize += dwDataSize;
  2258. // TRC( INF, _T("Fragment LAST block#=0x%x, total=0x%x\n"),
  2259. // pLast->cBlockNo, pSlot->dwTotalSize );
  2260. if ( pSlot->dwTotalSize != pSlot->dwExpectedTotalSize )
  2261. {
  2262. goto exitpt;
  2263. }
  2264. //
  2265. // ready, set, go
  2266. //
  2267. if (!_FragSlotToWave( pSlot, pReady, dwReadySize ))
  2268. {
  2269. goto exitpt;
  2270. }
  2271. rv = TRUE;
  2272. exitpt:
  2273. return rv;
  2274. }
  2275. BOOL
  2276. CRDPSound::_FragSlotFind(
  2277. PFRAGSLOT *ppFragSlot,
  2278. BYTE cBlockNo,
  2279. DWORD dwEstimatedSize
  2280. )
  2281. {
  2282. BOOL rv = FALSE;
  2283. PFRAGSLOT pIter = m_pFragSlots;
  2284. PFRAGSLOT pLastFree = NULL;
  2285. PFRAGSLOT pFound = NULL;
  2286. DWORD dwNewSize;
  2287. while( pIter )
  2288. {
  2289. //
  2290. // check if the slot hasn't been used for a while
  2291. //
  2292. if ( pIter->bUsed &&
  2293. (BYTE)( m_cLastReceivedBlock - pIter->cBlockNo ) < TSSND_BLOCKSONTHENET)
  2294. {
  2295. TRC( WRN, _T("Old frag found id %d, last id %d\n"),
  2296. pIter->cBlockNo, m_cLastReceivedBlock );
  2297. _FragSlotClear( pIter );
  2298. }
  2299. if ( !pIter->bUsed && NULL == pLastFree )
  2300. {
  2301. pLastFree = pIter;
  2302. }
  2303. if ( pIter->bUsed && pIter->cBlockNo == cBlockNo )
  2304. {
  2305. // found a block with same number
  2306. pFound = pIter;
  2307. break;
  2308. }
  2309. pIter = pIter->pNext;
  2310. }
  2311. if ( NULL == pFound && NULL != pLastFree )
  2312. {
  2313. //
  2314. // found a free block
  2315. //
  2316. pLastFree->bUsed = TRUE;
  2317. pLastFree->cBlockNo = cBlockNo;
  2318. pFound = pLastFree;
  2319. }
  2320. if ( NULL != pFound &&
  2321. pFound->dwAllocatedSize < dwEstimatedSize )
  2322. {
  2323. dwNewSize = dwEstimatedSize * 2;
  2324. PBYTE pNewData = (PBYTE)malloc( dwEstimatedSize * 2 );
  2325. if ( NULL == pNewData )
  2326. {
  2327. //
  2328. // we can't use this slot anymore
  2329. //
  2330. _FragSlotClear( pFound );
  2331. pFound = NULL;
  2332. goto exitpt;
  2333. }
  2334. memcpy( pNewData, pFound->pData, pFound->dwAllocatedSize );
  2335. pFound->dwAllocatedSize = dwNewSize;
  2336. free( pFound->pData );
  2337. pFound->pData = pNewData;
  2338. }
  2339. if ( NULL == pFound )
  2340. {
  2341. // allocate a new block
  2342. //
  2343. pFound = (PFRAGSLOT)malloc( sizeof( *pFound ));
  2344. if ( NULL == pFound )
  2345. {
  2346. goto exitpt;
  2347. }
  2348. dwNewSize = ( dwEstimatedSize > TSSND_BLOCKSIZE + RDPSND_SIGNATURE_SIZE )
  2349. ? dwEstimatedSize : TSSND_BLOCKSIZE + RDPSND_SIGNATURE_SIZE;
  2350. pFound->pData = (PBYTE)malloc( dwNewSize );
  2351. if ( NULL == pFound->pData )
  2352. {
  2353. free( pFound );
  2354. goto exitpt;
  2355. }
  2356. pFound->dwAllocatedSize = dwNewSize;
  2357. _FragSlotClear( pFound );
  2358. pFound->bUsed = TRUE;
  2359. pFound->cBlockNo = cBlockNo;
  2360. //
  2361. // add it to the list
  2362. //
  2363. pFound->pNext = m_pFragSlots;
  2364. m_pFragSlots = pFound;
  2365. }
  2366. *ppFragSlot = pFound;
  2367. rv = TRUE;
  2368. exitpt:
  2369. return rv;
  2370. }
  2371. VOID
  2372. CRDPSound::_FragSlotClear(
  2373. PFRAGSLOT pSlot
  2374. )
  2375. {
  2376. DWORD dwAllocated = pSlot->dwAllocatedSize;
  2377. PBYTE pData = pSlot->pData;
  2378. PFRAGSLOT pNext = pSlot->pNext;
  2379. memset( pSlot, 0, sizeof( *pSlot ));
  2380. pSlot->dwAllocatedSize = dwAllocated;
  2381. pSlot->pData = pData;
  2382. pSlot->pNext = pNext;
  2383. }
  2384. VOID
  2385. CRDPSound::_FragSlotFreeAll(
  2386. VOID
  2387. )
  2388. {
  2389. //
  2390. // free the fragment slots too
  2391. //
  2392. while( NULL != m_pFragSlots )
  2393. {
  2394. PFRAGSLOT pNext = m_pFragSlots->pNext;
  2395. free( m_pFragSlots->pData );
  2396. free( m_pFragSlots );
  2397. m_pFragSlots = pNext;
  2398. }
  2399. }
  2400. BOOL
  2401. CRDPSound::_FragSlotToWave(
  2402. PFRAGSLOT pSlot,
  2403. PSNDWAVE pWave,
  2404. DWORD dwWaveSize
  2405. )
  2406. {
  2407. BOOL rv = FALSE;
  2408. DWORD dwAvailDataSize;
  2409. DWORD dwBodySize;
  2410. ASSERT( pSlot->dwExpectedTotalSize == pSlot->dwTotalSize );
  2411. dwAvailDataSize = dwWaveSize - sizeof( *pWave );
  2412. if ( dwAvailDataSize < pSlot->dwTotalSize )
  2413. {
  2414. TRC( ERR, _T("_FragSlotToWave insufficient size to move the wave")
  2415. _T(" need %d, available %d\n"),
  2416. pSlot->dwTotalSize, dwAvailDataSize );
  2417. goto exitpt;
  2418. }
  2419. //
  2420. // when we support fragments, packets are encrypted
  2421. //
  2422. pWave->Prolog.Type = SNDC_WAVEENCRYPT;
  2423. dwBodySize = pSlot->dwTotalSize + sizeof( *pWave ) -
  2424. sizeof( pWave->Prolog );
  2425. ASSERT( dwBodySize < MAX_UDP_SIZE - sizeof( *pWave ));
  2426. pWave->Prolog.BodySize = (UINT16)dwBodySize;
  2427. pWave->wTimeStamp = pSlot->wTimeStamp;
  2428. pWave->wFormatNo = pSlot->wFormatNo;
  2429. pWave->dwBlockNo = pSlot->dwBlockNo;
  2430. memcpy( pWave + 1, pSlot->pData, pSlot->dwTotalSize );
  2431. //
  2432. // release the slot
  2433. //
  2434. _FragSlotClear( pSlot );
  2435. rv = TRUE;
  2436. exitpt:
  2437. return rv;
  2438. }
  2439. INT
  2440. WSInit(
  2441. VOID
  2442. )
  2443. {
  2444. WORD versionRequested;
  2445. WSADATA wsaData;
  2446. int intRC;
  2447. versionRequested = MAKEWORD(1, 1);
  2448. intRC = WSAStartup(versionRequested, &wsaData);
  2449. if (intRC != 0)
  2450. {
  2451. TRC(ERR, _T("Failed to initialize WinSock rc:%d\n"), intRC);
  2452. }
  2453. return intRC;
  2454. }
  2455. /*
  2456. * create signature bits
  2457. */
  2458. VOID
  2459. CRDPSound::SL_Signature(
  2460. PBYTE pSig,
  2461. DWORD dwBlockNo
  2462. )
  2463. {
  2464. BYTE ShaBits[A_SHA_DIGEST_LEN];
  2465. A_SHA_CTX SHACtx;
  2466. ASSERT( A_SHA_DIGEST_LEN > RDPSND_SIGNATURE_SIZE );
  2467. A_SHAInit(&SHACtx);
  2468. *((DWORD *)(m_EncryptKey + RANDOM_KEY_LENGTH)) = dwBlockNo;
  2469. A_SHAUpdate(&SHACtx, (PBYTE)m_EncryptKey, sizeof(m_EncryptKey));
  2470. A_SHAFinal(&SHACtx, ShaBits);
  2471. memcpy( pSig, ShaBits, RDPSND_SIGNATURE_SIZE );
  2472. }
  2473. /*
  2474. * signature which verifies the audio bits
  2475. */
  2476. VOID
  2477. CRDPSound::SL_AudioSignature(
  2478. PBYTE pSig,
  2479. DWORD dwBlockNo,
  2480. PBYTE pData,
  2481. DWORD dwDataSize
  2482. )
  2483. {
  2484. BYTE ShaBits[A_SHA_DIGEST_LEN];
  2485. A_SHA_CTX SHACtx;
  2486. A_SHAInit(&SHACtx);
  2487. *((DWORD *)(m_EncryptKey + RANDOM_KEY_LENGTH)) = dwBlockNo;
  2488. A_SHAUpdate(&SHACtx, (PBYTE)m_EncryptKey, sizeof(m_EncryptKey));
  2489. A_SHAUpdate(&SHACtx, pData, dwDataSize );
  2490. A_SHAFinal(&SHACtx, ShaBits);
  2491. memcpy( pSig, ShaBits, RDPSND_SIGNATURE_SIZE );
  2492. }
  2493. /*
  2494. * encrypt/decrypt a block of data
  2495. *
  2496. */
  2497. BOOL
  2498. CRDPSound::SL_Encrypt( PBYTE pBits, DWORD BlockNo, DWORD dwBitsLen )
  2499. {
  2500. BYTE ShaBits[A_SHA_DIGEST_LEN];
  2501. RC4_KEYSTRUCT rc4key;
  2502. #ifndef OS_WINCE
  2503. DWORD i;
  2504. #endif
  2505. PBYTE pbBuffer;
  2506. A_SHA_CTX SHACtx;
  2507. DWORD dw;
  2508. DWORD_PTR *pdwBits;
  2509. A_SHAInit(&SHACtx);
  2510. // SHA the static bits
  2511. *((DWORD *)(m_EncryptKey + RANDOM_KEY_LENGTH)) = BlockNo;
  2512. A_SHAUpdate(&SHACtx, (PBYTE)m_EncryptKey, sizeof(m_EncryptKey));
  2513. A_SHAFinal(&SHACtx, ShaBits);
  2514. rc4_key(&rc4key, A_SHA_DIGEST_LEN, ShaBits);
  2515. rc4(&rc4key, dwBitsLen, pBits);
  2516. return TRUE;
  2517. }
  2518. /*
  2519. * Function:
  2520. * _DbgPrintMessage
  2521. *
  2522. * Description:
  2523. * A tracing function
  2524. *
  2525. * Parameters:
  2526. * level - current message trace level
  2527. * format - message format
  2528. * ... - parameters
  2529. *
  2530. */
  2531. VOID
  2532. _cdecl
  2533. _DbgPrintMessage(LPCTSTR level, LPCTSTR format, ...)
  2534. {
  2535. TCHAR szBuffer[256];
  2536. va_list arglist;
  2537. if (ALV == level)
  2538. return;
  2539. va_start (arglist, format);
  2540. StringCchVPrintf(szBuffer, SIZE_TCHARS(szBuffer), format, arglist);
  2541. va_end (arglist);
  2542. #ifndef OS_WINCE
  2543. OutputDebugString(level);
  2544. OutputDebugString(szBuffer);
  2545. #endif // !OS_WINCE
  2546. }