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.

831 lines
18 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. vcint.cpp
  5. Abstract:
  6. This module contains virtual channel interface routines.
  7. Author:
  8. madan appiah (madana) 16-Sep-1998
  9. Revision History:
  10. --*/
  11. #include "precom.h"
  12. #define TRC_FILE "vcint"
  13. #include "cclip.h"
  14. #include "vcint.h"
  15. #include "rdpdrcom.h"
  16. #include "drdbg.h"
  17. #include "rdpsndc.h"
  18. VOID
  19. VCAPITYPE
  20. RDPDR_InitEventFnEx(
  21. IN PVOID lpUserParam,
  22. IN PVOID pInitHandle,
  23. IN UINT event,
  24. IN PVOID pData,
  25. IN UINT dataLength
  26. )
  27. /*++
  28. Routine Description:
  29. Handles InitEvent callbacks by delegating to the connection manager.
  30. Arguments:
  31. - pInitHandle - a handle uniquely identifying this connection
  32. - event - the event that has occurred - see CHANNEL_EVENT_XXX defines
  33. - pData - data associated with the event - see CHANNEL_EVENT_XXX defines
  34. - dataLength - length of the data.
  35. Return Value:
  36. None
  37. --*/
  38. {
  39. CRDPSound *pSound = NULL;
  40. DC_BEGIN_FN("InitEventFn");
  41. ASSERT(lpUserParam != NULL);
  42. if(!lpUserParam)
  43. {
  44. return;
  45. }
  46. VCManager* pVCMgr = (VCManager*)lpUserParam;
  47. ASSERT(pVCMgr != NULL);
  48. if(!pVCMgr)
  49. {
  50. return;
  51. }
  52. CClip* pClip = pVCMgr->GetClip();
  53. ASSERT(pClip != NULL);
  54. if(!pClip)
  55. {
  56. return;
  57. }
  58. pVCMgr->ChannelInitEvent(pInitHandle, event, pData, dataLength);
  59. pClip->ClipInitEventFn(pInitHandle, event, pData, dataLength);
  60. if ( pVCMgr->GetInitData()->fEnableRedirectedAudio )
  61. {
  62. pSound = pVCMgr->GetSound();
  63. if ( NULL != pSound )
  64. {
  65. pSound->InitEventFn( pInitHandle, event, pData, dataLength );
  66. }
  67. }
  68. if(CHANNEL_EVENT_TERMINATED == event)
  69. {
  70. //CLEANUP
  71. pSound = pVCMgr->GetSound();
  72. if ( NULL != pSound )
  73. delete pSound;
  74. delete pVCMgr;
  75. delete pClip;
  76. }
  77. DC_END_FN();
  78. return;
  79. }
  80. VOID
  81. VCAPITYPE
  82. RDPDR_OpenEventFn(
  83. IN LPVOID lpUserParam,
  84. IN ULONG openHandle,
  85. IN UINT event,
  86. IN PVOID pData,
  87. IN UINT32 dataLength,
  88. IN UINT32 totalLength,
  89. IN UINT32 dataFlags
  90. )
  91. /*++
  92. Routine Description:
  93. Handles OpenEvent callbacks by delegating to the connection manager.
  94. Arguments:
  95. openHandle - a handle uniquely identifying this channel
  96. event - event that has occurred - see CHANNEL_EVENT_XXX below
  97. pData - data received
  98. dataLength - length of the data
  99. totalLength - total length of data written by the Server
  100. dataFlags - flags, zero, one or more of:
  101. - 0x01 - beginning of data from a single write operation at the Server
  102. - 0x02 - end of data from a single write operation at the Server.
  103. Return Value:
  104. None
  105. --*/
  106. {
  107. DC_BEGIN_FN("OpenEventFn");
  108. TRC_NRM((TB, _T("Event %x, handle %lx, datalength %ld, dataFlags %lx"),
  109. event, openHandle, dataLength, dataFlags));
  110. ASSERT(lpUserParam != NULL);
  111. if(!lpUserParam)
  112. {
  113. return;
  114. }
  115. ((VCManager*)lpUserParam)->ChannelOpenEvent(openHandle, event, pData, dataLength,
  116. totalLength, dataFlags);
  117. DC_END_FN();
  118. return;
  119. }
  120. #ifdef OS_WIN32
  121. BOOL DCAPI
  122. #else //OS_WIN32
  123. BOOL __loadds DCAPI
  124. #endif //OS_WIN32
  125. RDPDR_VirtualChannelEntryEx(
  126. IN PCHANNEL_ENTRY_POINTS_EX pEntryPoints,
  127. IN PVOID pInitHandle
  128. )
  129. /*++
  130. Routine Description:
  131. Exported API called by the Virtual Channels
  132. Arguments:
  133. pEntryPoints - Entry point structure containing all callback methods.
  134. Return Value:
  135. None.
  136. --*/
  137. {
  138. BOOL rv = FALSE;
  139. VCManager* pcmMgr = NULL;
  140. CClip* pClip = NULL;
  141. CRDPSound *pSound = NULL;
  142. CHANNEL_DEF aChannel[3];
  143. UINT uiRet;
  144. PCHANNEL_INIT_HANDLE pChanInitHandle;
  145. PRDPDR_DATA pRdpDrInitSettings;
  146. DC_BEGIN_FN("VirtualChannelEntry");
  147. if( pEntryPoints->cbSize < sizeof(CHANNEL_ENTRY_POINTS_EX) ) {
  148. //
  149. // we don't have all entry points we need.
  150. //
  151. goto exitpt;
  152. }
  153. pChanInitHandle = (PCHANNEL_INIT_HANDLE)pInitHandle;
  154. pRdpDrInitSettings = (PRDPDR_DATA)pChanInitHandle->lpInternalAddinParam;
  155. ASSERT(pRdpDrInitSettings);
  156. if(!pRdpDrInitSettings)
  157. {
  158. goto exitpt;
  159. }
  160. pcmMgr = new VCManager(pEntryPoints);
  161. pRdpDrInitSettings->pUpdateDeviceObj = pcmMgr;
  162. if( pcmMgr == NULL ) {
  163. goto exitpt;
  164. }
  165. pcmMgr->SetInitData( pRdpDrInitSettings);
  166. pClip = new CClip(pcmMgr);
  167. if( pClip == NULL ) {
  168. goto exitpt;
  169. }
  170. pcmMgr->SetClip( pClip);
  171. pClip->SetVCInitHandle( pInitHandle);
  172. pSound = new CRDPSound( pEntryPoints, pInitHandle );
  173. if ( NULL == pSound ) {
  174. goto exitpt;
  175. }
  176. pcmMgr->SetSound( pSound );
  177. if (!pClip->ClipChannelEntry(pEntryPoints)) {
  178. TRC_ALT((TB, _T("Clip rejected VirtualChannelEntry")));
  179. goto exitpt;
  180. }
  181. memset(aChannel[0].name, 0, CHANNEL_NAME_LEN);
  182. memcpy(aChannel[0].name, PRDR_VC_CHANNEL_NAME, strlen(PRDR_VC_CHANNEL_NAME));
  183. aChannel[0].options = CHANNEL_OPTION_COMPRESS_RDP;
  184. memset(aChannel[1].name, 0, CHANNEL_NAME_LEN);
  185. memcpy(aChannel[1].name, CLIP_CHANNEL, sizeof(CLIP_CHANNEL));
  186. aChannel[1].options = CHANNEL_OPTION_ENCRYPT_RDP |
  187. CHANNEL_OPTION_COMPRESS_RDP |
  188. CHANNEL_OPTION_SHOW_PROTOCOL;
  189. memset( aChannel[2].name, 0, CHANNEL_NAME_LEN );
  190. memcpy( aChannel[2].name, _SNDVC_NAME, sizeof( _SNDVC_NAME ));
  191. aChannel[2].options = CHANNEL_OPTION_ENCRYPT_RDP;
  192. uiRet = (pEntryPoints->pVirtualChannelInitEx)(pcmMgr,
  193. pInitHandle,
  194. aChannel,
  195. 3,
  196. VIRTUAL_CHANNEL_VERSION_WIN2000,
  197. RDPDR_InitEventFnEx);
  198. TRC_NRM((TB, _T("VirtualChannelInit rc[%d]"), uiRet));
  199. if( uiRet != CHANNEL_RC_OK ) {
  200. goto exitpt;
  201. }
  202. rv = TRUE;
  203. exitpt:
  204. if ( !rv )
  205. {
  206. if ( NULL != pClip )
  207. delete pClip;
  208. if ( NULL != pSound )
  209. delete pSound;
  210. if ( NULL != pcmMgr )
  211. delete pcmMgr;
  212. }
  213. DC_END_FN();
  214. return(rv);
  215. }
  216. /* ----------------------------------------------------------------*/
  217. VCManager::VCManager(
  218. IN PCHANNEL_ENTRY_POINTS_EX pEntries
  219. )
  220. /*++
  221. Routine Description:
  222. Initilizes the system, and determines which processor to load for
  223. the given operating system.
  224. Arguments:
  225. Id - Connection Id
  226. Return Value:
  227. None
  228. --*/
  229. {
  230. DC_BEGIN_FN("VCManager::VCManager");
  231. _bState = STATE_UNKNOWN;
  232. _ChannelEntries = *pEntries;
  233. _pProcObj = NULL;
  234. _hVCHandle = NULL;
  235. _Buffer.uiLength = _Buffer.uiAvailLen = 0;
  236. _Buffer.pbData = NULL;
  237. _hVCOpenHandle = 0;
  238. //_pRdpDrInitSettings receives settings from the core
  239. _pRdpDrInitSettings = NULL;
  240. DC_END_FN();
  241. }
  242. VOID
  243. VCManager::ChannelWrite(
  244. IN LPVOID pData,
  245. IN UINT uiLength
  246. )
  247. /*++
  248. Routine Description:
  249. Abstracts writing data to the channel for the processing components
  250. If the write should fail, this function releases the outgoing buffer.
  251. Arguments:
  252. pData - Data to be written
  253. uiLength - Length of data to write
  254. Return Value:
  255. None
  256. --*/
  257. {
  258. DC_BEGIN_FN("VCManager::ChannelWrite");
  259. TRC_NRM((TB, _T("Data[%p] Length[%d]"), pData, uiLength));
  260. #if DBG
  261. if( !IsValidHeader(pData) ) {
  262. TRC_ERR((TB, _T("Sending an invalid dr header")));
  263. }
  264. #endif // DBG
  265. UINT uiRet;
  266. uiRet = (_ChannelEntries.pVirtualChannelWriteEx)( _hVCHandle,
  267. _hVCOpenHandle,
  268. pData,
  269. uiLength,
  270. (PVOID)pData);
  271. TRC_NRM((TB, _T("VirtualChannelWrite Ret [%d]"), uiRet));
  272. switch (uiRet) {
  273. case CHANNEL_RC_OK:
  274. break;
  275. case CHANNEL_RC_NOT_INITIALIZED:
  276. ASSERT(FALSE);
  277. break;
  278. case CHANNEL_RC_NOT_CONNECTED:
  279. {
  280. //Valid to receive this because we can be getting
  281. //disconnected on another thread
  282. TRC_ALT((TB,_T("Write failed with CHANNEL_RC_NOT_CONNECTED")));
  283. }
  284. break;
  285. case CHANNEL_RC_BAD_CHANNEL_HANDLE:
  286. ASSERT(FALSE);
  287. break;
  288. case CHANNEL_RC_NULL_DATA:
  289. ASSERT(FALSE);
  290. break;
  291. case CHANNEL_RC_ZERO_LENGTH:
  292. ASSERT(FALSE);
  293. break;
  294. default:
  295. TRC_ALT((TB, _T("Unknown return value for VirtualChannelWrite[%d]\n"), uiRet));
  296. break;
  297. }
  298. //
  299. // Release the buffer on failure.
  300. //
  301. if (uiRet != CHANNEL_RC_OK) {
  302. delete []((BYTE *)pData);
  303. }
  304. DC_END_FN();
  305. return;
  306. }
  307. UINT
  308. VCManager::ChannelWriteEx(
  309. IN LPVOID pData,
  310. IN UINT uiLength
  311. )
  312. /*++
  313. Routine Description:
  314. Abstracts writing data to the channel for the processing components.
  315. This version returns the return value back
  316. If this function fails the buffer is released.
  317. Arguments:
  318. pData - Data to be written
  319. uiLength - Length of data to write
  320. Return Value:
  321. CHANNEL_RC_OK
  322. CHANNEL_RC_NOT_INITIALIZED
  323. CHANNEL_RC_NOT_CONNECTED
  324. CHANNEL_RC_BAD_CHANNEL_HANDLE
  325. CHANNEL_RC_NULL_DATA
  326. CHANNEL_RC_ZERO_LENGTH
  327. --*/
  328. {
  329. DC_BEGIN_FN("VCManager::ChannelWriteEx");
  330. TRC_NRM((TB, _T("Data[%p] Length[%d]"), pData, uiLength));
  331. #if DBG
  332. if( !IsValidHeader(pData) ) {
  333. TRC_ERR((TB, _T("Sending an invalid dr header")));
  334. }
  335. #endif // DBG
  336. UINT uiRet;
  337. uiRet = (_ChannelEntries.pVirtualChannelWriteEx)( _hVCHandle,
  338. _hVCOpenHandle,
  339. pData,
  340. uiLength,
  341. (PVOID)pData);
  342. if (uiRet != CHANNEL_RC_OK) {
  343. TRC_NRM((TB, _T("VirtualChannelWrite Ret [%d]"), uiRet));
  344. delete []((BYTE *)pData);
  345. }
  346. return uiRet;
  347. }
  348. /*++
  349. Routine Description:
  350. Closes the virtual channel
  351. Arguments:
  352. None
  353. Return Value:
  354. CHANNEL_RC_OK on Success - see VirtualChannelClose docs in MSDN
  355. --*/
  356. UINT
  357. VCManager::ChannelClose()
  358. {
  359. UINT uiRet;
  360. DC_BEGIN_FN("ChannelClose");
  361. uiRet = (_ChannelEntries.pVirtualChannelCloseEx)( _hVCHandle,
  362. _hVCOpenHandle);
  363. if (uiRet != CHANNEL_RC_OK) {
  364. TRC_ERR((TB, _T("VirtualChannelClose Ret [%d]"), uiRet));
  365. }
  366. DC_END_FN();
  367. return uiRet;
  368. }
  369. VOID
  370. VCManager::ChannelInitEvent(
  371. IN PVOID pInitHandle,
  372. IN UINT uiEvent,
  373. IN PVOID pData,
  374. IN UINT uiDataLength
  375. )
  376. /*++
  377. Routine Description:
  378. Handles InitEvent callbacks
  379. Arguments:
  380. pInitHandle - a handle uniquely identifying this connection
  381. uiEvent - the event that has occurred - see CHANNEL_EVENT_XXX defines
  382. pData - data associated with the event - see CHANNEL_EVENT_XXX defines
  383. uiDataLength - length of the data.
  384. Return Value:
  385. None
  386. --*/
  387. {
  388. DC_BEGIN_FN("VCManager::ChannelInitEvent");
  389. UNREFERENCED_PARAMETER( pData );
  390. UNREFERENCED_PARAMETER( uiDataLength );
  391. UINT uiRetVal;
  392. TRC_NRM((TB, _T("Event %d, handle %p"), uiEvent, pInitHandle));
  393. if (_hVCHandle == NULL)
  394. _hVCHandle = pInitHandle;
  395. switch (uiEvent) {
  396. case CHANNEL_EVENT_INITIALIZED :
  397. ASSERT(_bState == STATE_UNKNOWN);
  398. _bState = CHANNEL_EVENT_INITIALIZED;
  399. break;
  400. case CHANNEL_EVENT_CONNECTED :
  401. ASSERT((_bState == CHANNEL_EVENT_INITIALIZED) ||
  402. (_bState == CHANNEL_EVENT_DISCONNECTED));
  403. //
  404. // Create the platform-specific Processing instance
  405. //
  406. TRC_NRM((TB, _T("VCManager::ChannelnitEvent: Creating processor.")));
  407. _pProcObj = ProcObj::Instantiate(this);
  408. if( _pProcObj == NULL ) {
  409. TRC_NRM((TB, _T("Error creating processor.")));
  410. return;
  411. }
  412. //
  413. // Initialize the proc obj instance
  414. //
  415. uiRetVal = (UINT) _pProcObj->Initialize();
  416. if( uiRetVal != ERROR_SUCCESS ) {
  417. delete _pProcObj;
  418. _pProcObj = NULL;
  419. return;
  420. }
  421. //
  422. // Open the virtual channel interface.
  423. //
  424. uiRetVal =
  425. (_ChannelEntries.pVirtualChannelOpenEx)(
  426. _hVCHandle,
  427. &_hVCOpenHandle,
  428. PRDR_VC_CHANNEL_NAME,
  429. &RDPDR_OpenEventFn);
  430. TRC_NRM((TB, _T("VirtualChannelOpen Ret[%d]"), uiRetVal));
  431. _bState = CHANNEL_EVENT_CONNECTED;
  432. break;
  433. case CHANNEL_EVENT_V1_CONNECTED :
  434. ASSERT((_bState == CHANNEL_EVENT_INITIALIZED) ||
  435. (_bState == CHANNEL_EVENT_DISCONNECTED));
  436. _bState = CHANNEL_EVENT_V1_CONNECTED;
  437. break;
  438. case CHANNEL_EVENT_DISCONNECTED :
  439. //ASSERT((_bState == CHANNEL_EVENT_CONNECTED) ||
  440. // (_bState == CHANNEL_EVENT_V1_CONNECTED));
  441. if (_pProcObj) {
  442. delete _pProcObj;
  443. _pProcObj = NULL;
  444. }
  445. _bState = CHANNEL_EVENT_DISCONNECTED;
  446. break;
  447. case CHANNEL_EVENT_TERMINATED :
  448. /*
  449. DbgAssert((_bState == CHANNEL_EVENT_DISCONNECTED) ||
  450. (_bState == CHANNEL_EVENT_V1_CONNECTED) ||
  451. (_bState == CHANNEL_EVENT_INITIALIZED),
  452. ("_bState[%d] is in inproper position to be TERMINATED",
  453. _bState));
  454. */
  455. if (_pProcObj) {
  456. delete _pProcObj;
  457. _pProcObj = NULL;
  458. }
  459. _bState = CHANNEL_EVENT_TERMINATED;
  460. break;
  461. default:
  462. TRC_ALT((TB, _T("Unknown Event in ChannelInitEvent recieved[%d]\n"),
  463. uiEvent));
  464. break;
  465. }
  466. DC_END_FN();
  467. return;
  468. }
  469. VOID
  470. VCManager::ChannelOpenEvent(
  471. IN ULONG ulOpenHandle,
  472. IN UINT uiEvent,
  473. IN PVOID pData,
  474. IN UINT32 uiDataLength,
  475. IN UINT32 uiTotalLength,
  476. IN UINT32 uiDataFlags
  477. )
  478. /*++
  479. Routine Description:
  480. Handles OpenEvent callbacks
  481. Arguments:
  482. ulOpenHandle - a handle uniquely identifying this channel
  483. uiEvent - event that has occurred - see CHANNEL_EVENT_XXX below
  484. pData - data received
  485. uiDataLength - length of the data
  486. uiTotalLength - total length of data written by the Server
  487. uiDataFlags - flags, zero, one or more of:
  488. - 0x01 - beginning of data from a single write operation at the Server
  489. - 0x02 - end of data from a single write operation at the Server.
  490. Return Value:
  491. None
  492. --*/
  493. {
  494. DC_BEGIN_FN("VCManager::ChannelOpenEvent");
  495. TRC_NRM((TB, _T("Event[0x%x], uiDataLength[%ld], uiDataFlags[0x%lx]"),
  496. uiEvent, uiDataLength, uiDataFlags));
  497. ASSERT(ulOpenHandle == _hVCOpenHandle);
  498. //
  499. // not for us, simply return.
  500. //
  501. if( ulOpenHandle != _hVCOpenHandle ) {
  502. return;
  503. }
  504. ASSERT(uiDataLength <= uiTotalLength);
  505. //
  506. // total length much less, give up.
  507. //
  508. if( uiDataLength > uiTotalLength ) {
  509. return;
  510. }
  511. //
  512. // free data buffer on write complete.
  513. //
  514. if ((uiEvent == CHANNEL_EVENT_WRITE_COMPLETE) ||
  515. (uiEvent == CHANNEL_EVENT_WRITE_CANCELLED)) {
  516. delete []((BYTE *)pData);
  517. TRC_NRM((TB, _T("VCManager::ChannelOpenEvent:S:WriteComplete")));
  518. return;
  519. }
  520. ASSERT(uiEvent == CHANNEL_EVENT_DATA_RECEIVED);
  521. //
  522. // alocated new buffer for incoming data.
  523. //
  524. if( (uiDataFlags == CHANNEL_FLAG_FIRST) ||
  525. (uiDataFlags == CHANNEL_FLAG_ONLY) ) {
  526. TRC_NRM((TB, _T("Allocating %ld bytes"), uiTotalLength));
  527. _Buffer.pbData = new BYTE[uiTotalLength];
  528. if( _Buffer.pbData == NULL ) {
  529. TRC_ERR((TB,_T("_Buffer.pbData is NULL")));
  530. return;
  531. }
  532. _Buffer.uiLength = 0;
  533. _Buffer.uiAvailLen = uiTotalLength;
  534. }
  535. if( _Buffer.pbData == NULL ) {
  536. TRC_ERR((TB,_T("_Buffer.pbData is NULL")));
  537. return;
  538. }
  539. //
  540. // copy first part of the data in the buffer.
  541. //
  542. if (uiDataFlags == CHANNEL_FLAG_FIRST) {
  543. TRC_NRM((TB, _T("CHANNEL_FLAG_FIRST Creating:[%ld]"), uiTotalLength));
  544. memcpy(_Buffer.pbData, pData, uiDataLength);
  545. _Buffer.uiLength = uiDataLength;
  546. TRC_NRM((TB, _T("VCManager::ChannelOpenEvent[1]")));
  547. return;
  548. }
  549. //
  550. // add data to the buffer.
  551. //
  552. UINT32 uiLen;
  553. uiLen = _Buffer.uiLength + uiDataLength;
  554. ASSERT(_Buffer.uiAvailLen >= uiLen);
  555. //
  556. // too much data arrived.
  557. //
  558. if( _Buffer.uiAvailLen < uiLen ) {
  559. TRC_ERR((TB,_T("Too much data arrived: avail:0x%x arrived:0x%x"),
  560. _Buffer.uiAvailLen, uiLen));
  561. //
  562. // Disconnect the channel
  563. //
  564. ChannelClose();
  565. return;
  566. }
  567. memcpy( _Buffer.pbData + _Buffer.uiLength, pData, uiDataLength );
  568. _Buffer.uiLength = uiLen;
  569. if (uiDataFlags == CHANNEL_FLAG_MIDDLE) {
  570. TRC_NRM((TB, _T("VCManager::ChannelOpenEvent[2]")));
  571. return;
  572. }
  573. //
  574. // complete data buffer available, process it.
  575. //
  576. _pProcObj->ProcessServerPacket(&_Buffer);
  577. DC_END_FN();
  578. return;
  579. }
  580. void
  581. VCManager::OnDeviceChange(WPARAM wParam, LPARAM lParam)
  582. /*++
  583. Routine Description:
  584. Receive a device change notification from the control.
  585. Pass it to the proc obj to handle.
  586. Arguments:
  587. Return Value:
  588. None.
  589. --*/
  590. {
  591. if (_pProcObj != NULL) {
  592. _pProcObj->OnDeviceChange(wParam, lParam);
  593. }
  594. }