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.

1433 lines
31 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. ptreg.cpp
  5. Abstract:
  6. Implementation of Plug-Terminal Registration classes.
  7. --*/
  8. #include "stdafx.h"
  9. #include "PTReg.h"
  10. #include "manager.h"
  11. #include <atlwin.h>
  12. #include <atlwin.cpp>
  13. //
  14. // CPlugTerminal class implementation
  15. // Create free thread marshaler
  16. //
  17. HRESULT CPlugTerminal::FinalConstruct(void)
  18. {
  19. LOG((MSP_TRACE, "CPlugTerminal::FinalConstruct - enter"));
  20. HRESULT hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(),
  21. & m_pFTM );
  22. if ( FAILED(hr) )
  23. {
  24. LOG((MSP_ERROR, "CPlugTerminal::FinalConstruct - "
  25. "create FTM returned 0x%08x; exit", hr));
  26. return hr;
  27. }
  28. LOG((MSP_TRACE, "CPlugTerminal::FinalConstruct - exit S_OK"));
  29. return S_OK;
  30. }
  31. //
  32. // CPlugTerminal class implementation
  33. // --- ITPTRegTerminal interface ---
  34. //
  35. STDMETHODIMP CPlugTerminal::get_Name(
  36. /*[out, retval]*/ BSTR* pName
  37. )
  38. {
  39. //
  40. // Critical section
  41. //
  42. CLock lock(m_CritSect);
  43. LOG((MSP_TRACE, "CPlugTerminal::get_Name - enter"));
  44. //
  45. // Validates argument
  46. //
  47. if( TM_IsBadWritePtr( pName, sizeof(BSTR)) )
  48. {
  49. LOG((MSP_ERROR, "CPlugTerminal::get_Name exit -"
  50. "pName invalid, returns E_POINTER"));
  51. return E_POINTER;
  52. }
  53. //
  54. // Validates the name
  55. //
  56. if( IsBadStringPtr( m_Terminal.m_bstrName, (UINT)-1) )
  57. {
  58. LOG((MSP_ERROR, "CPlugTerminal::get_Name exit -"
  59. "m_bstrName invalid, returns E_UNEXPECTED"));
  60. return E_UNEXPECTED;
  61. }
  62. //
  63. // Return the name
  64. //
  65. *pName = SysAllocString( m_Terminal.m_bstrName );
  66. //
  67. // Validates SysAllocString
  68. //
  69. if( *pName == NULL )
  70. {
  71. LOG((MSP_ERROR, "CPlugTerminal::get_Name exit -"
  72. "SysAllocString failed, returns E_OUTOFMEMORY"));
  73. return E_OUTOFMEMORY;
  74. }
  75. LOG((MSP_TRACE, "CPlugTerminal::get_Name - exit"));
  76. return S_OK;
  77. }
  78. STDMETHODIMP CPlugTerminal::put_Name(
  79. /*[in]*/ BSTR bstrName
  80. )
  81. {
  82. //
  83. // Critical section
  84. //
  85. CLock lock(m_CritSect);
  86. LOG((MSP_TRACE, "CPlugTerminal::put_Name - enter"));
  87. //
  88. // Validates argument
  89. //
  90. if(IsBadStringPtr( bstrName, (UINT)-1) )
  91. {
  92. LOG((MSP_ERROR, "CPlugTerminal::put_Name exit -"
  93. "bstrName invalid, returns E_POINTER"));
  94. return E_POINTER;
  95. }
  96. //
  97. // Clean-up the old name
  98. //
  99. if(!IsBadStringPtr( m_Terminal.m_bstrName, (UINT)-1) )
  100. {
  101. SysFreeString( m_Terminal.m_bstrName );
  102. m_Terminal.m_bstrName = NULL;
  103. }
  104. //
  105. // Set the new name
  106. //
  107. m_Terminal.m_bstrName = SysAllocString( bstrName );
  108. //
  109. // Validates SysAllocString
  110. //
  111. if( NULL == m_Terminal.m_bstrName )
  112. {
  113. LOG((MSP_ERROR, "CPlugTerminal::put_Name exit -"
  114. "SysAllocString failed, returns E_OUTOFMEMORY"));
  115. return E_OUTOFMEMORY;
  116. }
  117. LOG((MSP_TRACE, "CPlugTerminal::put_Name - exit"));
  118. return S_OK;
  119. }
  120. STDMETHODIMP CPlugTerminal::get_Company(
  121. /*[out, retval]*/ BSTR* pCompany
  122. )
  123. {
  124. //
  125. // Critical section
  126. //
  127. CLock lock(m_CritSect);
  128. LOG((MSP_TRACE, "CPlugTerminal::get_Company - enter"));
  129. //
  130. // Validates argument
  131. //
  132. if( TM_IsBadWritePtr( pCompany, sizeof(BSTR)) )
  133. {
  134. LOG((MSP_ERROR, "CPlugTerminal::get_Company exit -"
  135. "pCompany invalid, returns E_POINTER"));
  136. return E_POINTER;
  137. }
  138. //
  139. // Validates the company
  140. //
  141. if( IsBadStringPtr( m_Terminal.m_bstrCompany, (UINT)-1) )
  142. {
  143. LOG((MSP_ERROR, "CPlugTerminal::get_Company exit -"
  144. "m_bstrCompany invalid, returns E_UNEXPECTED"));
  145. return E_UNEXPECTED;
  146. }
  147. //
  148. // Return the Company
  149. //
  150. *pCompany = SysAllocString( m_Terminal.m_bstrCompany );
  151. //
  152. // Validates SysAllocString
  153. //
  154. if( *pCompany == NULL )
  155. {
  156. LOG((MSP_ERROR, "CPlugTerminal::get_Company exit -"
  157. "SysAllocString failed, returns E_OUTOFMEMORY"));
  158. return E_OUTOFMEMORY;
  159. }
  160. LOG((MSP_TRACE, "CPlugTerminal::get_Company - exit"));
  161. return S_OK;
  162. }
  163. STDMETHODIMP CPlugTerminal::put_Company(
  164. /*[in]*/ BSTR bstrCompany
  165. )
  166. {
  167. //
  168. // Critical section
  169. //
  170. CLock lock(m_CritSect);
  171. LOG((MSP_TRACE, "CPlugTerminal::put_Company - enter"));
  172. //
  173. // Validates argument
  174. //
  175. if(IsBadStringPtr( bstrCompany, (UINT)-1) )
  176. {
  177. LOG((MSP_ERROR, "CPlugTerminal::put_Company exit -"
  178. "bstrCompany invalid, returns E_POINTER"));
  179. return E_POINTER;
  180. }
  181. //
  182. // Clean-up the old company
  183. //
  184. if(!IsBadStringPtr( m_Terminal.m_bstrCompany, (UINT)-1) )
  185. {
  186. SysFreeString( m_Terminal.m_bstrCompany );
  187. m_Terminal.m_bstrCompany = NULL;
  188. }
  189. //
  190. // Set the new company
  191. //
  192. m_Terminal.m_bstrCompany = SysAllocString( bstrCompany );
  193. //
  194. // Validates SysAllocString
  195. //
  196. if( NULL == m_Terminal.m_bstrCompany )
  197. {
  198. LOG((MSP_ERROR, "CPlugTerminal::put_Company exit -"
  199. "SysAllocString failed, returns E_OUTOFMEMORY"));
  200. return E_OUTOFMEMORY;
  201. }
  202. LOG((MSP_TRACE, "CPlugTerminal::put_Company - exit"));
  203. return S_OK;
  204. }
  205. STDMETHODIMP CPlugTerminal::get_Version(
  206. /*[out, retval]*/ BSTR* pVersion
  207. )
  208. {
  209. //
  210. // Critical section
  211. //
  212. CLock lock(m_CritSect);
  213. LOG((MSP_TRACE, "CPlugTerminal::get_Version - enter"));
  214. //
  215. // Validates argument
  216. //
  217. if( TM_IsBadWritePtr( pVersion, sizeof(BSTR)) )
  218. {
  219. LOG((MSP_ERROR, "CPlugTerminal::get_Version exit -"
  220. "pVersion invalid, returns E_POINTER"));
  221. return E_POINTER;
  222. }
  223. //
  224. // Validates the version
  225. //
  226. if( IsBadStringPtr( m_Terminal.m_bstrVersion, (UINT)-1) )
  227. {
  228. LOG((MSP_ERROR, "CPlugTerminal::get_Version exit -"
  229. "m_bstrVersion invalid, returns E_UNEXPECTED"));
  230. return E_UNEXPECTED;
  231. }
  232. //
  233. // Return the Version
  234. //
  235. *pVersion = SysAllocString( m_Terminal.m_bstrVersion );
  236. //
  237. // Validates SysAllocString
  238. //
  239. if( *pVersion == NULL )
  240. {
  241. LOG((MSP_ERROR, "CPlugTerminal::get_Version exit -"
  242. "SysAllocString failed, returns E_OUTOFMEMORY"));
  243. return E_OUTOFMEMORY;
  244. }
  245. LOG((MSP_TRACE, "CPlugTerminal::get_Version - exit"));
  246. return S_OK;
  247. }
  248. STDMETHODIMP CPlugTerminal::put_Version(
  249. /*[in]*/ BSTR bstrVersion
  250. )
  251. {
  252. //
  253. // Critical section
  254. //
  255. CLock lock(m_CritSect);
  256. LOG((MSP_TRACE, "CPlugTerminal::put_Version - enter"));
  257. //
  258. // Validates argument
  259. //
  260. if(IsBadStringPtr( bstrVersion, (UINT)-1) )
  261. {
  262. LOG((MSP_ERROR, "CPlugTerminal::put_Version exit -"
  263. "bstrVersion invalid, returns E_POINTER"));
  264. return E_POINTER;
  265. }
  266. //
  267. // Clean-up the old version
  268. //
  269. if(!IsBadStringPtr( m_Terminal.m_bstrVersion, (UINT)-1) )
  270. {
  271. SysFreeString( m_Terminal.m_bstrVersion );
  272. m_Terminal.m_bstrVersion = NULL;
  273. }
  274. //
  275. // Set the new Version
  276. //
  277. m_Terminal.m_bstrVersion = SysAllocString( bstrVersion );
  278. //
  279. // Validates SysAllocString
  280. //
  281. if( NULL == m_Terminal.m_bstrVersion )
  282. {
  283. LOG((MSP_ERROR, "CPlugTerminal::put_Version exit -"
  284. "SysAllocString failed, returns E_OUTOFMEMORY"));
  285. return E_OUTOFMEMORY;
  286. }
  287. LOG((MSP_TRACE, "CPlugTerminal::put_Version - exit"));
  288. return S_OK;
  289. }
  290. STDMETHODIMP CPlugTerminal::get_TerminalClass(
  291. /*[out, retval]*/ BSTR* pTerminalClass
  292. )
  293. {
  294. //
  295. // Critical section
  296. //
  297. CLock lock(m_CritSect);
  298. LOG((MSP_TRACE, "CPlugTerminal::get_TerminalClass - enter"));
  299. //
  300. // Validates argument
  301. //
  302. if( TM_IsBadWritePtr( pTerminalClass, sizeof(BSTR)) )
  303. {
  304. LOG((MSP_ERROR, "CPlugTerminal::get_TerminalClass exit -"
  305. "pTerminalClass invalid, returns E_POINTER"));
  306. return E_POINTER;
  307. }
  308. //
  309. // Return the TerminalClass
  310. //
  311. LPOLESTR lpszTerminalClass = NULL;
  312. HRESULT hr = StringFromCLSID(
  313. m_Terminal.m_clsidTerminalClass,
  314. &lpszTerminalClass
  315. );
  316. if( FAILED(hr) )
  317. {
  318. LOG((MSP_ERROR, "CPlugTerminal::get_TerminalClass exit -"
  319. "StringFromCLSID failed, returns 0x%08x", hr));
  320. return hr;
  321. }
  322. *pTerminalClass = SysAllocString( lpszTerminalClass );
  323. // Clean-up
  324. CoTaskMemFree( lpszTerminalClass );
  325. //
  326. // Validates SysAllocString
  327. //
  328. if( *pTerminalClass == NULL )
  329. {
  330. LOG((MSP_ERROR, "CPlugTerminal::get_TerminalClass exit -"
  331. "SysAllocString failed, returns E_OUTOFMEMORY"));
  332. return E_OUTOFMEMORY;
  333. }
  334. LOG((MSP_TRACE, "CPlugTerminal::get_TerminalClass - exit"));
  335. return S_OK;
  336. }
  337. STDMETHODIMP CPlugTerminal::put_TerminalClass(
  338. /*[in]*/ BSTR bstrTerminalClass
  339. )
  340. {
  341. //
  342. // Critical section
  343. //
  344. CLock lock(m_CritSect);
  345. LOG((MSP_TRACE, "CPlugTerminal::put_TerminalClass - enter"));
  346. //
  347. // Validates argument
  348. //
  349. if(IsBadStringPtr( bstrTerminalClass, (UINT)-1) )
  350. {
  351. LOG((MSP_ERROR, "CPlugTerminal::put_TerminalClass exit -"
  352. "bstrTerminalClass invalid, returns E_POINTER"));
  353. return E_POINTER;
  354. }
  355. //
  356. // Is a real CLSID?
  357. //
  358. CLSID clsidTerminalClass;
  359. HRESULT hr = CLSIDFromString(bstrTerminalClass, &clsidTerminalClass);
  360. if( FAILED(hr) )
  361. {
  362. LOG((MSP_ERROR, "CPlugTerminal::put_TerminalClass exit -"
  363. "bstrTerminalClass is not a CLSID, returns E_INVALIDARG"));
  364. return E_INVALIDARG;
  365. }
  366. //
  367. // Clean-up the old TerminalClass
  368. //
  369. m_Terminal.m_clsidTerminalClass = clsidTerminalClass;
  370. LOG((MSP_TRACE, "CPlugTerminal::put_TerminalClass - exit"));
  371. return S_OK;
  372. }
  373. STDMETHODIMP CPlugTerminal::get_CLSID(
  374. /*[out, retval]*/ BSTR* pCLSID
  375. )
  376. {
  377. //
  378. // Critical section
  379. //
  380. CLock lock(m_CritSect);
  381. LOG((MSP_TRACE, "CPlugTerminal::get_CLSID - enter"));
  382. //
  383. // Validates argument
  384. //
  385. if( TM_IsBadWritePtr( pCLSID, sizeof(BSTR)) )
  386. {
  387. LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -"
  388. "pCLSID invalid, returns E_POINTER"));
  389. return E_POINTER;
  390. }
  391. if( m_Terminal.m_clsidCOM == CLSID_NULL )
  392. {
  393. LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -"
  394. "clsid is NULL, returns E_UNEXPECTED"));
  395. return E_UNEXPECTED;
  396. }
  397. //
  398. // Return the CLSID
  399. //
  400. LPOLESTR lpszCLSID = NULL;
  401. HRESULT hr = StringFromCLSID( m_Terminal.m_clsidCOM, &lpszCLSID);
  402. if( FAILED(hr) )
  403. {
  404. LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -"
  405. "StringFromCLSID failed, returns 0x%08x", hr));
  406. return hr;
  407. }
  408. *pCLSID = SysAllocString( lpszCLSID );
  409. // Clean-up
  410. CoTaskMemFree( lpszCLSID );
  411. //
  412. // Validates SysAllocString
  413. //
  414. if( *pCLSID == NULL )
  415. {
  416. LOG((MSP_ERROR, "CPlugTerminal::get_CLSID exit -"
  417. "SysAllocString failed, returns E_OUTOFMEMORY"));
  418. return E_OUTOFMEMORY;
  419. }
  420. LOG((MSP_TRACE, "CPlugTerminal::get_CLSID - exit"));
  421. return S_OK;
  422. }
  423. STDMETHODIMP CPlugTerminal::put_CLSID(
  424. /*[in]*/ BSTR bstrCLSID
  425. )
  426. {
  427. //
  428. // Critical section
  429. //
  430. CLock lock(m_CritSect);
  431. LOG((MSP_TRACE, "CPlugTerminal::put_CLSID - enter"));
  432. //
  433. // Validates argument
  434. //
  435. if(IsBadStringPtr( bstrCLSID, (UINT)-1) )
  436. {
  437. LOG((MSP_ERROR, "CPlugTerminal::put_CLSID exit -"
  438. "bstrCLSID invalid, returns E_POINTER"));
  439. return E_POINTER;
  440. }
  441. //
  442. // Is a real CLSID?
  443. //
  444. CLSID clsidCOM;
  445. HRESULT hr = CLSIDFromString(bstrCLSID, &clsidCOM);
  446. if( FAILED(hr) )
  447. {
  448. LOG((MSP_ERROR, "CPlugTerminal::put_CLSID exit -"
  449. "bstrCLSID is not a CLSID, returns E_INVALIDARG"));
  450. return E_INVALIDARG;
  451. }
  452. //
  453. // Clean-up the old CLSID
  454. //
  455. m_Terminal.m_clsidCOM = clsidCOM;
  456. LOG((MSP_TRACE, "CPlugTerminal::put_CLSID - exit"));
  457. return S_OK;
  458. }
  459. STDMETHODIMP CPlugTerminal::get_Direction(
  460. /*[out, retval]*/ TMGR_DIRECTION* pDirection
  461. )
  462. {
  463. //
  464. // Critical section
  465. //
  466. CLock lock(m_CritSect);
  467. LOG((MSP_TRACE, "CPlugTerminal::get_Direction - enter"));
  468. //
  469. // Validates argument
  470. //
  471. if( TM_IsBadWritePtr( pDirection, sizeof(long)) )
  472. {
  473. LOG((MSP_ERROR, "CPlugTerminal::get_Direction exit -"
  474. "pDirections invalid, returns E_POINTER"));
  475. return E_POINTER;
  476. }
  477. //
  478. // Return the Direction
  479. //
  480. *pDirection = (TMGR_DIRECTION)m_Terminal.m_dwDirections;
  481. LOG((MSP_TRACE, "CPlugTerminal::get_Direction - exit"));
  482. return S_OK;
  483. }
  484. STDMETHODIMP CPlugTerminal::put_Direction(
  485. /*[in]*/ TMGR_DIRECTION nDirection
  486. )
  487. {
  488. //
  489. // Critical section
  490. //
  491. CLock lock(m_CritSect);
  492. LOG((MSP_TRACE, "CPlugTerminal::put_Direction - enter"));
  493. if( nDirection == 0 )
  494. {
  495. LOG((MSP_ERROR, "CPlugTerminal::put_Direction exit -"
  496. "nDirections invalid, returns E_INVALIDARG"));
  497. return E_INVALIDARG;
  498. }
  499. if( (nDirection & (
  500. ((long)TMGR_TD_RENDER) |
  501. ((long)TMGR_TD_CAPTURE))) != nDirection )
  502. {
  503. LOG((MSP_ERROR, "CPlugTerminal::put_Direction exit -"
  504. "nDirections invalid, returns E_INVALIDARG"));
  505. return E_INVALIDARG;
  506. }
  507. //
  508. // Set the new direction
  509. //
  510. m_Terminal.m_dwDirections = nDirection;
  511. LOG((MSP_TRACE, "CPlugTerminal::put_Direction - exit S_OK"));
  512. return S_OK;
  513. }
  514. STDMETHODIMP CPlugTerminal::get_MediaTypes(
  515. /*[out, retval]*/ long* pMediaTypes
  516. )
  517. {
  518. //
  519. // Critical section
  520. //
  521. CLock lock(m_CritSect);
  522. LOG((MSP_TRACE, "CPlugTerminal::get_MediaTypes - enter"));
  523. //
  524. // Validates argument
  525. //
  526. if( TM_IsBadWritePtr( pMediaTypes, sizeof(long)) )
  527. {
  528. LOG((MSP_ERROR, "CPlugTerminal::get_MediaTypes exit -"
  529. "pMediaTypes invalid, returns E_POINTER"));
  530. return E_POINTER;
  531. }
  532. //
  533. // Return the MediaTypes
  534. //
  535. *pMediaTypes = (long)m_Terminal.m_dwMediaTypes;
  536. LOG((MSP_TRACE, "CPlugTerminal::get_MediaTypes - exit"));
  537. return S_OK;
  538. }
  539. STDMETHODIMP CPlugTerminal::put_MediaTypes(
  540. /*[in]*/ long nMediaTypes
  541. )
  542. {
  543. //
  544. // Critical section
  545. //
  546. CLock lock(m_CritSect);
  547. LOG((MSP_TRACE, "CPlugTerminal::put_MediaTypes - enter"));
  548. if( nMediaTypes == 0)
  549. {
  550. LOG((MSP_ERROR, "CPlugTerminal::put_MediaTypes exit -"
  551. "nMediaTypes invalid, returns E_INVALIDARG"));
  552. return E_INVALIDARG;
  553. }
  554. if( (nMediaTypes & (
  555. ((long)TAPIMEDIATYPE_AUDIO) |
  556. ((long)TAPIMEDIATYPE_VIDEO) |
  557. ((long)TAPIMEDIATYPE_MULTITRACK))) != nMediaTypes )
  558. {
  559. LOG((MSP_ERROR, "CPlugTerminal::put_MediaTypes exit -"
  560. "nMediaTypes invalid, returns E_INVALIDARG"));
  561. return E_INVALIDARG;
  562. }
  563. //
  564. // Set the new direction
  565. //
  566. m_Terminal.m_dwMediaTypes = nMediaTypes;
  567. LOG((MSP_TRACE, "CPlugTerminal::put_MediaTypes - exit"));
  568. return S_OK;
  569. }
  570. STDMETHODIMP CPlugTerminal::Add(
  571. /*[in]*/ BSTR bstrSuperclass
  572. )
  573. {
  574. //
  575. // Critical section
  576. //
  577. CLock lock(m_CritSect);
  578. LOG((MSP_TRACE, "CPlugTerminal::Add - enter"));
  579. //
  580. // Validates argument
  581. //
  582. if(IsBadStringPtr( bstrSuperclass, (UINT)-1) )
  583. {
  584. LOG((MSP_ERROR, "CPlugTerminal::Add exit -"
  585. "bstrTermClassCLSID invalid, returns E_POINTER"));
  586. return E_POINTER;
  587. }
  588. //
  589. // Is a real CLSID
  590. //
  591. CLSID clsidSuperclass = CLSID_NULL;
  592. HRESULT hr = E_FAIL;
  593. hr = CLSIDFromString( bstrSuperclass, &clsidSuperclass);
  594. if( FAILED(hr) )
  595. {
  596. LOG((MSP_ERROR, "CPlugTerminal::Add exit -"
  597. "bstrTermClassCLSID is not a CLSID, returns E_INVALIDARG"));
  598. return E_INVALIDARG;
  599. }
  600. //
  601. // Add
  602. //
  603. hr = m_Terminal.Add( clsidSuperclass );
  604. LOG((MSP_TRACE, "CPlugTerminal::Add - exit 0x%08x", hr));
  605. return hr;
  606. }
  607. STDMETHODIMP CPlugTerminal::Delete(
  608. /*[in]*/ BSTR bstrSuperclass
  609. )
  610. {
  611. //
  612. // Critical section
  613. //
  614. CLock lock(m_CritSect);
  615. LOG((MSP_TRACE, "CPlugTerminal::Delete - enter"));
  616. //
  617. // Validates argument
  618. //
  619. if(IsBadStringPtr( bstrSuperclass, (UINT)-1) )
  620. {
  621. LOG((MSP_ERROR, "CPlugTerminal::Delete exit -"
  622. "bstrTermClassCLSID invalid, returns E_POINTER"));
  623. return E_POINTER;
  624. }
  625. //
  626. // Is a real CLSID
  627. //
  628. CLSID clsidSuperclass = CLSID_NULL;
  629. HRESULT hr = E_FAIL;
  630. hr = CLSIDFromString( bstrSuperclass, &clsidSuperclass);
  631. if( FAILED(hr) )
  632. {
  633. LOG((MSP_ERROR, "CPlugTerminal::Delete exit -"
  634. "bstrTermClassCLSID is not a CLSID, returns E_INVALIDARG"));
  635. return E_INVALIDARG;
  636. }
  637. //
  638. // Delete
  639. //
  640. hr = m_Terminal.Delete( clsidSuperclass );
  641. LOG((MSP_TRACE, "CPlugTerminal::Delete - exit 0x%08x", hr));
  642. return hr;
  643. }
  644. STDMETHODIMP CPlugTerminal::GetTerminalClassInfo(
  645. /*[in]*/ BSTR bstrSuperclass
  646. )
  647. {
  648. //
  649. // Critical section
  650. //
  651. CLock lock(m_CritSect);
  652. LOG((MSP_TRACE, "CPlugTerminal::GetTerminal - enter"));
  653. //
  654. // Validates argument
  655. //
  656. if(IsBadStringPtr( bstrSuperclass, (UINT)-1) )
  657. {
  658. LOG((MSP_ERROR, "CPlugTerminal::GetTerminal exit -"
  659. "bstrTermClassCLSID invalid, returns E_POINTER"));
  660. return E_POINTER;
  661. }
  662. //
  663. // Is a real CLSID
  664. //
  665. CLSID clsidSuperclass = CLSID_NULL;
  666. HRESULT hr = E_FAIL;
  667. hr = CLSIDFromString( bstrSuperclass, &clsidSuperclass);
  668. if( FAILED(hr) )
  669. {
  670. LOG((MSP_ERROR, "CPlugTerminal::GetTerminal exit -"
  671. "bstrTermClassCLSID is not a CLSID, returns E_INVALIDARG"));
  672. return E_INVALIDARG;
  673. }
  674. //
  675. // Get terminal
  676. //
  677. hr = m_Terminal.Get( clsidSuperclass );
  678. LOG((MSP_TRACE, "CPlugTerminal::GetTerminal - exit 0x%08x", hr));
  679. return hr;
  680. }
  681. //
  682. // CPlugTerminalSuperlass class implementation
  683. // Create free thread marshaler
  684. //
  685. HRESULT CPlugTerminalSuperclass::FinalConstruct(void)
  686. {
  687. LOG((MSP_TRACE, "CPlugTerminalSuperclass::FinalConstruct - enter"));
  688. HRESULT hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(),
  689. & m_pFTM );
  690. if ( FAILED(hr) )
  691. {
  692. LOG((MSP_ERROR, "CPlugTerminalSuperclass::FinalConstruct - "
  693. "create FTM returned 0x%08x; exit", hr));
  694. return hr;
  695. }
  696. LOG((MSP_TRACE, "CPlugTerminalSuperclass::FinalConstruct - exit S_OK"));
  697. return S_OK;
  698. }
  699. //
  700. // CPlugTerminalSuperlass class implementation
  701. // --- ITPTRegTerminalClass interface ---
  702. //
  703. STDMETHODIMP CPlugTerminalSuperclass::get_Name(
  704. /*[out, retval]*/ BSTR* pName
  705. )
  706. {
  707. //
  708. // Critical section
  709. //
  710. CLock lock(m_CritSect);
  711. LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_Name - enter"));
  712. //
  713. // Validates argument
  714. //
  715. if( TM_IsBadWritePtr( pName, sizeof(BSTR)) )
  716. {
  717. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_Name exit -"
  718. "pName invalid, returns E_POINTER"));
  719. return E_POINTER;
  720. }
  721. //
  722. // Validate internal name
  723. //
  724. if( IsBadStringPtr( m_Superclass.m_bstrName, (UINT)-1) )
  725. {
  726. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_Name exit -"
  727. "bstrName invalid, returns E_UNEXPECTED"));
  728. return E_UNEXPECTED;
  729. }
  730. //
  731. // Returns name
  732. //
  733. *pName = SysAllocString( m_Superclass.m_bstrName);
  734. //
  735. // Validate SysAllocString
  736. //
  737. if( *pName == NULL )
  738. {
  739. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_Name exit -"
  740. "SysAllocString failed, returns E_OUTOFMEMORY"));
  741. return E_OUTOFMEMORY;
  742. }
  743. LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_Name - exit"));
  744. return S_OK;
  745. }
  746. STDMETHODIMP CPlugTerminalSuperclass::put_Name(
  747. /*[in]*/ BSTR bstrName
  748. )
  749. {
  750. //
  751. // Critical section
  752. //
  753. CLock lock(m_CritSect);
  754. LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_Name - enter"));
  755. //
  756. // Validates argument
  757. //
  758. if(IsBadStringPtr( bstrName, (UINT)-1) )
  759. {
  760. LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_Name exit -"
  761. "bstrName invalid, returns E_POINTER"));
  762. return E_POINTER;
  763. }
  764. //
  765. // Clean-up the old name
  766. //
  767. if(!IsBadStringPtr( m_Superclass.m_bstrName, (UINT)-1) )
  768. {
  769. SysFreeString( m_Superclass.m_bstrName );
  770. m_Superclass.m_bstrName = NULL;
  771. }
  772. //
  773. // Set the new name
  774. //
  775. m_Superclass.m_bstrName = SysAllocString( bstrName );
  776. //
  777. // Validates the sysAllocString
  778. //
  779. if( NULL == m_Superclass.m_bstrName )
  780. {
  781. LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_Name exit -"
  782. "SysAllocString failed, returns E_OUTOFMEMORY"));
  783. return E_OUTOFMEMORY;
  784. }
  785. LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_Name - exit"));
  786. return S_OK;
  787. }
  788. STDMETHODIMP CPlugTerminalSuperclass::get_CLSID(
  789. /*[out, retval]*/ BSTR* pCLSIDClass
  790. )
  791. {
  792. //
  793. // Critical section
  794. //
  795. CLock lock(m_CritSect);
  796. LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_CLSIDClass - enter"));
  797. //
  798. // Validates argument
  799. //
  800. if( TM_IsBadWritePtr( pCLSIDClass, sizeof(BSTR)) )
  801. {
  802. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_CLSIDClass exit -"
  803. "pCLSIDClass invalid, returns E_POINTER"));
  804. return E_POINTER;
  805. }
  806. //
  807. // Returns CLSID
  808. //
  809. LPOLESTR lpszSuperclassCLSID = NULL;
  810. HRESULT hr = StringFromCLSID( m_Superclass.m_clsidSuperclass, &lpszSuperclassCLSID);
  811. if( FAILED(hr) )
  812. {
  813. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_CLSIDClass exit -"
  814. "StringFromClSID failed, returns 0x%08x", hr));
  815. return hr;
  816. }
  817. *pCLSIDClass = SysAllocString( lpszSuperclassCLSID);
  818. // Clean-up
  819. CoTaskMemFree( lpszSuperclassCLSID );
  820. //
  821. // Validates SysAllocString
  822. //
  823. if( *pCLSIDClass == NULL )
  824. {
  825. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_CLSIDClass exit -"
  826. "SysAllocString failed, returns E_OUTOFMEMORY"));
  827. return E_OUTOFMEMORY;
  828. }
  829. LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_CLSIDClass - exit"));
  830. return S_OK;
  831. }
  832. STDMETHODIMP CPlugTerminalSuperclass::put_CLSID(
  833. /*[in]*/ BSTR bstrCLSIDClass
  834. )
  835. {
  836. //
  837. // Critical section
  838. //
  839. CLock lock(m_CritSect);
  840. LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_CLSIDClass - enter"));
  841. //
  842. // Validates argument
  843. //
  844. if(IsBadStringPtr( bstrCLSIDClass, (UINT)-1) )
  845. {
  846. LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_CLSIDClass exit -"
  847. "bstrCLSIDClass invalid, returns E_POINTER"));
  848. return E_POINTER;
  849. }
  850. //
  851. // Is a real CLSID?
  852. //
  853. CLSID clsidSuperclassClSID;
  854. HRESULT hr = CLSIDFromString(bstrCLSIDClass, &clsidSuperclassClSID);
  855. if( FAILED(hr) )
  856. {
  857. LOG((MSP_ERROR, "CPlugTerminalSuperclass::put_CLSIDClass exit -"
  858. "bstrCLSIDClass is not a CLSID, returns E_INVALIDARG"));
  859. return E_INVALIDARG;
  860. }
  861. //
  862. // Clean-up the old CLSID
  863. //
  864. m_Superclass.m_clsidSuperclass = clsidSuperclassClSID;
  865. LOG((MSP_TRACE, "CPlugTerminalSuperclass::put_CLSIDClasse - exit"));
  866. return S_OK;
  867. }
  868. STDMETHODIMP CPlugTerminalSuperclass::Add(
  869. )
  870. {
  871. //
  872. // Critical section
  873. //
  874. CLock lock(m_CritSect);
  875. LOG((MSP_TRACE, "CPlugTerminalSuperclass::Add - enter"));
  876. //
  877. // Add terminal class
  878. //
  879. HRESULT hr = E_FAIL;
  880. hr = m_Superclass.Add();
  881. LOG((MSP_TRACE, "CPlugTerminalSuperclass::Add - exit 0x%08x", hr));
  882. return hr;
  883. }
  884. STDMETHODIMP CPlugTerminalSuperclass::Delete(
  885. )
  886. {
  887. //
  888. // Critical section
  889. //
  890. CLock lock(m_CritSect);
  891. LOG((MSP_TRACE, "CPlugTerminalSuperclass::Deletee - enter"));
  892. //
  893. // Delete terminalc class
  894. //
  895. HRESULT hr = E_FAIL;
  896. hr = m_Superclass.Delete();
  897. LOG((MSP_TRACE, "CPlugTerminalSuperclass::Delete - exit 0x%08x",hr));
  898. return hr;
  899. }
  900. STDMETHODIMP CPlugTerminalSuperclass::GetTerminalSuperclassInfo(
  901. )
  902. {
  903. //
  904. // Critical section
  905. //
  906. CLock lock(m_CritSect);
  907. LOG((MSP_TRACE, "CPlugTerminalSuperclass::GetTerminalSuperclassInfo - enter"));
  908. //
  909. // Get terminal class from registry
  910. //
  911. HRESULT hr = E_FAIL;
  912. hr = m_Superclass.Get();
  913. LOG((MSP_TRACE, "CPlugTerminalSuperclass::GetTerminalSuperclassInfo - exit 0x%08x",hr));
  914. return hr;
  915. }
  916. STDMETHODIMP CPlugTerminalSuperclass::get_TerminalClasses(
  917. /*[out, retval]*/ VARIANT* pVarTerminals
  918. )
  919. {
  920. //
  921. // Critical section
  922. //
  923. CLock lock(m_CritSect);
  924. LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_TerminalClasses - enter"));
  925. //
  926. // Validates argument
  927. //
  928. if( TM_IsBadWritePtr( pVarTerminals, sizeof(VARIANT)) )
  929. {
  930. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -"
  931. "pTerminals invalid, returns E_POINTER"));
  932. return E_POINTER;
  933. }
  934. //
  935. // reset the output argument
  936. //
  937. pVarTerminals->parray = NULL;
  938. pVarTerminals->vt = VT_EMPTY;
  939. //
  940. // List the terminals
  941. //
  942. HRESULT hr = E_FAIL;
  943. CLSID* pTerminals = NULL;
  944. DWORD dwTerminals = 0;
  945. hr = m_Superclass.ListTerminalClasses( 0,
  946. &pTerminals,
  947. &dwTerminals
  948. );
  949. if( FAILED(hr) )
  950. {
  951. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -"
  952. "ListTerminalClasses failed, returns 0x%08x", hr));
  953. return hr;
  954. }
  955. //
  956. // Create a safe array for the terminasl
  957. //
  958. SAFEARRAY* psaTerminals = NULL;
  959. SAFEARRAYBOUND rgsabound;
  960. rgsabound.lLbound = 1;
  961. rgsabound.cElements = dwTerminals;
  962. psaTerminals = SafeArrayCreate(
  963. VT_BSTR,
  964. 1,
  965. &rgsabound);
  966. if( psaTerminals == NULL )
  967. {
  968. // Clean-up
  969. delete[] pTerminals;
  970. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -"
  971. "SafeArrayCreate failed, returns E_OUTOFMEMORY"));
  972. return E_OUTOFMEMORY;
  973. }
  974. //
  975. // Copies into the safe array the elements
  976. //
  977. for( DWORD dwTerminal = 0; dwTerminal < dwTerminals; dwTerminal++)
  978. {
  979. LPOLESTR lpszTerminalClass = NULL;
  980. hr = StringFromCLSID( pTerminals[dwTerminal], &lpszTerminalClass);
  981. if( FAILED(hr) )
  982. {
  983. // Clean-up
  984. delete[] pTerminals;
  985. SafeArrayDestroy( psaTerminals );
  986. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -"
  987. "StringFromCLSID failed, returns 0x%08x", hr));
  988. return hr;
  989. }
  990. BSTR bstrTerminalClass = SysAllocString( lpszTerminalClass );
  991. CoTaskMemFree( lpszTerminalClass );
  992. if( bstrTerminalClass == NULL )
  993. {
  994. // Clean-up
  995. delete[] pTerminals;
  996. SafeArrayDestroy( psaTerminals );
  997. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -"
  998. "sysAloocString failed, returns E_OUTOFMEMORY"));
  999. return E_OUTOFMEMORY;
  1000. }
  1001. // Put the element into the array
  1002. long nIndex = (long)(dwTerminal+1);
  1003. hr = SafeArrayPutElement( psaTerminals, &nIndex, bstrTerminalClass );
  1004. if( FAILED(hr) )
  1005. {
  1006. // Clean-up
  1007. delete[] pTerminals;
  1008. SafeArrayDestroy( psaTerminals );
  1009. SysFreeString( bstrTerminalClass );
  1010. LOG((MSP_ERROR, "CPlugTerminalSuperclass::get_TerminalClasses exit -"
  1011. "SafeArrayPutElement failed, returns 0x%08x", hr));
  1012. return hr;
  1013. }
  1014. }
  1015. // Clean-up
  1016. delete[] pTerminals;
  1017. // Return values
  1018. pVarTerminals->parray = psaTerminals;
  1019. pVarTerminals->vt = VT_ARRAY | VT_BSTR;
  1020. LOG((MSP_TRACE, "CPlugTerminalSuperclass::get_TerminalClasses - exit 0x%08x", hr));
  1021. return hr;
  1022. }
  1023. STDMETHODIMP CPlugTerminalSuperclass::EnumerateTerminalClasses(
  1024. OUT IEnumTerminalClass** ppTerminals
  1025. )
  1026. {
  1027. LOG((MSP_TRACE, "CPlugTerminalSuperclass::EnumerateTerminalClasses - enter"));
  1028. //
  1029. // Validate argument
  1030. //
  1031. if( TM_IsBadWritePtr( ppTerminals, sizeof(IEnumTerminalClass*)) )
  1032. {
  1033. LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -"
  1034. "ppTerminals invalid, returns E_POINTER"));
  1035. return E_POINTER;
  1036. }
  1037. CLSID* pTerminals = NULL;
  1038. DWORD dwTerminals = 0;
  1039. HRESULT hr = m_Superclass.ListTerminalClasses( 0,
  1040. &pTerminals,
  1041. &dwTerminals
  1042. );
  1043. if( FAILED(hr) )
  1044. {
  1045. LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -"
  1046. "ListTerminalClasses failed, returns 0x%08x", hr));
  1047. return hr;
  1048. }
  1049. //
  1050. // Create a buffer with exactly dwTerminals size
  1051. //
  1052. CLSID* pTerminalsCLSID = new CLSID[dwTerminals];
  1053. if( pTerminalsCLSID == NULL )
  1054. {
  1055. LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -"
  1056. "new operator failed, returns E_OUTOFMEMORY"));
  1057. return E_OUTOFMEMORY;
  1058. }
  1059. //
  1060. // Copies into the new buffer
  1061. //
  1062. memcpy( pTerminalsCLSID, pTerminals, sizeof(CLSID)*dwTerminals);
  1063. //
  1064. // Delete the old buffer
  1065. //
  1066. delete[] pTerminals;
  1067. //
  1068. // Create the enumerator
  1069. //
  1070. typedef CSafeComEnum<IEnumTerminalClass,
  1071. &IID_IEnumTerminalClass,
  1072. GUID, _Copy<GUID> > CEnumerator;
  1073. CComObject<CEnumerator> *pEnum = NULL;
  1074. hr = CComObject<CEnumerator>::CreateInstance(&pEnum);
  1075. if( FAILED(hr) )
  1076. {
  1077. delete[] pTerminalsCLSID;
  1078. LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -"
  1079. "CreateInstance failed, returns 0x%08x", hr));
  1080. return hr;
  1081. }
  1082. //
  1083. // Initialize enumerator
  1084. //
  1085. hr = pEnum->Init(pTerminalsCLSID,
  1086. pTerminalsCLSID+dwTerminals,
  1087. NULL,
  1088. AtlFlagTakeOwnership);
  1089. if( FAILED(hr) )
  1090. {
  1091. delete pEnum;
  1092. delete[] pTerminalsCLSID;
  1093. LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit -"
  1094. "Init failed, returns 0x%08x", hr));
  1095. return hr;
  1096. }
  1097. //
  1098. // Query for the desired interface.
  1099. //
  1100. hr = pEnum->_InternalQueryInterface(
  1101. IID_IEnumTerminalClass,
  1102. (void**) ppTerminals
  1103. );
  1104. if ( FAILED(hr) )
  1105. {
  1106. LOG((MSP_ERROR, "CPlugTerminalSuperclass::EnumerateTerminalClasses exit - "
  1107. "can't get enumerator interface - exit 0x%08x", hr));
  1108. delete pEnum;
  1109. delete[] pTerminalsCLSID;
  1110. return hr;
  1111. }
  1112. LOG((MSP_TRACE, "CPlugTerminalSuperclass::EnumerateTerminalClasses - exit S_OK"));
  1113. return S_OK;
  1114. }
  1115. // eof