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.

639 lines
18 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. // Copyright (c) 1998-1999 Microsoft Corporation
  5. //
  6. // Name: Manager.cpp
  7. //
  8. // Description: Implementation of the CTerminalManager object
  9. //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include "termmgr.h"
  13. #include "manager.h"
  14. #include "PTUtil.h"
  15. #define INSTANTIATE_GUIDS_NOW
  16. #include "allterm.h"
  17. #undef INSTANTIATE_GUIDS_NOW
  18. //////////////////////////////////////////////////////////////////////////////
  19. //////////////////////////////////////////////////////////////////////////////
  20. //////////////////////////////////////////////////////////////////////////////
  21. //////////////////////////////////////////////////////////////////////////////
  22. //////////////////////////////////////////////////////////////////////////////
  23. //
  24. // CTerminalManager constructor
  25. //
  26. // Parameters:
  27. // None.
  28. //
  29. // Returns:
  30. // Nothing.
  31. //
  32. CTerminalManager::CTerminalManager()
  33. {
  34. LOG((MSP_TRACE, "CTerminalManager::CTerminalManager - enter"));
  35. LOG((MSP_TRACE, "CTerminalManager::CTerminalManager - exit"));
  36. }
  37. //////////////////////////////////////////////////////////////////////////////
  38. //////////////////////////////////////////////////////////////////////////////
  39. //////////////////////////////////////////////////////////////////////////////
  40. // GetDynamicTerminalClasses
  41. //
  42. // The MSP will call this method to get a list of dynamic terminal classes
  43. // that the Terminal Manager supports. The MSP is responsible for allocating
  44. // and deallocating the ppTerminals buffer.
  45. //
  46. // Parameters:
  47. // dwMediaType: [in] A DWORD bitmask consisting of one or more
  48. // TAPIMEDIATYPEs ORed together. Most MSPs will
  49. // pass in (DWORD) (TAPIMEDIATYPE_AUDIO |
  50. // TAPIMEDIATYPE_VIDEO). If an MSP is only
  51. // interested in terminal classes that can be used
  52. // to create terminals with a particular media
  53. // type, it may pass in that media type instead
  54. // (e.g., TAPIMEDIATYPE_AUDIO).
  55. // pdwNumClasses: [in, out] Pointer to a DWORD. On entry, indicates
  56. // the size of the buffer pointed to in
  57. // pTerminalClasses. On success, it will be filled
  58. // in with the actual number of class IIDs returned.
  59. // If the buffer is not big enough, the method will
  60. // return TAPI_E_NOTENOUGHMEMORY, and it will be
  61. // filled in the with number of IIDs needed.
  62. // pTerminalClasses: [out] On success, filled in with an array of terminal
  63. // class IIDs that are supported by the MSP for this
  64. // address. This value may be NULL, in which case
  65. // pdwNumClasses will return the needed buffer size.
  66. //
  67. // Returns:
  68. // S_OK Success.
  69. // E_POINTER A pointer argument is invalid.
  70. // TAPI_E_NOTENOUGHMEMORY The specified buffer is not large enough to
  71. // contain all of the available dynamic
  72. // terminal classes.
  73. STDMETHODIMP CTerminalManager::GetDynamicTerminalClasses(
  74. IN DWORD dwMediaTypes,
  75. IN OUT DWORD * pdwNumClasses,
  76. OUT IID * pTerminalClasses
  77. )
  78. {
  79. //
  80. // no shared data = no locking here
  81. //
  82. LOG((MSP_TRACE, "CTerminalManager::GetDynamicTerminalClasses - enter"));
  83. //
  84. // Check parameters.
  85. //
  86. if ( TM_IsBadWritePtr(pdwNumClasses, sizeof(DWORD) ) )
  87. {
  88. LOG((MSP_ERROR, "CTerminalManager::GetDynamicTerminalClasses - "
  89. "bad NumClasses pointer - returning E_POINTER"));
  90. return E_POINTER;
  91. }
  92. //
  93. // Let's find also the temrinals from the registry
  94. //
  95. CLSID* pTerminals = NULL;
  96. DWORD dwTerminals = 0;
  97. HRESULT hr = E_FAIL;
  98. hr = CPTUtil::ListTerminalClasses(
  99. dwMediaTypes,
  100. &pTerminals,
  101. &dwTerminals
  102. );
  103. if( FAILED(hr) )
  104. {
  105. LOG((MSP_ERROR, "CTerminalManager::GetDynamicTerminalClasses - "
  106. "ListTerminalClasses failed - returning 0x%08x", hr));
  107. return hr;
  108. }
  109. //
  110. // If the caller is just asking for the needed buffer size, tell them.
  111. //
  112. if (pTerminalClasses == NULL)
  113. {
  114. *pdwNumClasses = dwTerminals;
  115. delete[] pTerminals;
  116. LOG((MSP_TRACE, "CTerminalManager::GetDynamicTerminalClasses - "
  117. "provided needed buffer size - "
  118. "returning S_OK"));
  119. return S_OK;
  120. }
  121. //
  122. // Otherwise, the caller is asking for the terminal classes.
  123. //
  124. if ( TM_IsBadWritePtr(pTerminalClasses, (*pdwNumClasses) * sizeof(IID) ) )
  125. {
  126. delete[] pTerminals;
  127. LOG((MSP_ERROR, "CTerminalManager::GetDynamicTerminalClasses - "
  128. "bad TerminalClasses pointer - returning E_POINTER"));
  129. return E_POINTER;
  130. }
  131. //
  132. // See if the caller gave us enough buffer space to return all the terminal
  133. // classes. If not, tell them so and stop.
  134. //
  135. if ( dwTerminals > *pdwNumClasses )
  136. {
  137. //
  138. // Fill in the number of classes that are available.
  139. //
  140. *pdwNumClasses = dwTerminals;
  141. delete[] pTerminals;
  142. LOG((MSP_ERROR, "CTerminalManager::GetDynamicTerminalClasses - "
  143. "not enough space for requested info - "
  144. "returning TAPI_E_NOTENOUGHMEMORY"));
  145. return TAPI_E_NOTENOUGHMEMORY;
  146. }
  147. //
  148. // Copy the terminal classes that match this/these media type(s)
  149. // and direction(s).
  150. //
  151. //
  152. // Copy the terminals from registry
  153. //
  154. for( DWORD dwTerminal = 0; dwTerminal < dwTerminals; dwTerminal++)
  155. {
  156. pTerminalClasses[dwTerminal] = pTerminals[dwTerminal];
  157. }
  158. *pdwNumClasses = dwTerminals;
  159. delete[] pTerminals;
  160. LOG((MSP_TRACE, "CTerminalManager::GetDynamicTerminalClasses - exit S_OK"));
  161. return S_OK;
  162. }
  163. //////////////////////////////////////////////////////////////////////////////
  164. //////////////////////////////////////////////////////////////////////////////
  165. //////////////////////////////////////////////////////////////////////////////
  166. // CreateDynamicTerminal
  167. //
  168. // This method is called by the MSP to create a dynamic terminal object. The
  169. // Terminal Manager verifies that the MediaType and Direction are valid for
  170. // the terminal class being created. This call AddRef()s the terminal object
  171. // before returning it.
  172. //
  173. // Parameters:
  174. // iidTerminalClass: [in] IID of the terminal class to be created.
  175. // dwMediaType: [in] TAPI media type of the terminal to be created.
  176. // Direction: [in] Terminal direction of the terminal to be
  177. // created.
  178. // ppTerminal: [out] Returned created terminal object
  179. //
  180. // Returns:
  181. //
  182. // S_OK Success.
  183. // E_POINTER A pointer argument is invalid.
  184. // E_OUTOFMEMORY There is not enough memory to create the terminal object.
  185. // E_INVALIDARG The terminal class is invalid or not supported, or the media
  186. // type or direction is invalid for the indicated terminal
  187. // class.
  188. //
  189. STDMETHODIMP CTerminalManager::CreateDynamicTerminal(
  190. IN IUnknown * pOuterUnknown,
  191. IN IID iidTerminalClass,
  192. IN DWORD dwMediaType,
  193. IN TERMINAL_DIRECTION Direction,
  194. IN MSP_HANDLE htAddress,
  195. OUT ITTerminal ** ppTerminal
  196. )
  197. {
  198. //
  199. // no shared data = no locking here
  200. //
  201. LOG((MSP_TRACE, "CTerminalManager::CreateDynamicTerminal - enter"));
  202. //
  203. // Check parameters.
  204. // Only one media type can be set.
  205. //
  206. if ( (pOuterUnknown != NULL) &&
  207. IsBadReadPtr(pOuterUnknown, sizeof(IUnknown)) )
  208. {
  209. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  210. "outer unknown pointer invalid - returning E_POINTER"));
  211. return E_POINTER;
  212. }
  213. if ( TM_IsBadWritePtr(ppTerminal, sizeof(ITTerminal *)) )
  214. {
  215. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  216. "terminal output pointer invalid - returning E_POINTER"));
  217. return E_POINTER;
  218. }
  219. //
  220. // dwMediaType can be a combination of media types, but it still must be
  221. // legal
  222. //
  223. if ( !IsValidAggregatedMediaType(dwMediaType) )
  224. {
  225. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  226. "ivalid media type [%lx] requested - returning E_INVALIDARG", dwMediaType));
  227. return E_INVALIDARG;
  228. }
  229. //
  230. // Verify also TD_MULTITRACK_MIXED
  231. //
  232. if ( ( Direction != TD_CAPTURE ) &&
  233. ( Direction != TD_RENDER ) &&
  234. ( Direction != TD_MULTITRACK_MIXED))
  235. {
  236. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  237. "invalid direction requested - returning E_INVALIDARG"));
  238. return E_INVALIDARG;
  239. }
  240. //
  241. // Declare CLSID for plug-in terminal
  242. //
  243. CLSID clsidTerminal = CLSID_NULL;
  244. //
  245. // Go to find out the terminal in registry
  246. //
  247. HRESULT hr = E_FAIL;
  248. CPTTerminal Terminal;
  249. hr = CPTUtil::SearchForTerminal(
  250. iidTerminalClass,
  251. dwMediaType,
  252. Direction,
  253. &Terminal);
  254. if( FAILED(hr) )
  255. {
  256. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  257. "SearchForTerminal failed - returning 0x%08x", hr));
  258. return hr;
  259. }
  260. //
  261. // Using the CLSID field in our array entry, CoCreate the dynamic
  262. // terminal.
  263. //
  264. hr = CoCreateInstance(Terminal.m_clsidCOM,
  265. pOuterUnknown,
  266. CLSCTX_INPROC_SERVER,
  267. IID_ITTerminal,
  268. (void **) ppTerminal);
  269. if ( FAILED(hr) )
  270. {
  271. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  272. "CoCreateInstance of requested terminal failed - "
  273. "returning 0x%08x", hr));
  274. return hr;
  275. }
  276. //
  277. // Initialize the dynamic terminal instance with the media type
  278. // and direction.
  279. //
  280. ITPluggableTerminalInitialization * pTerminalInitialization;
  281. hr = (*ppTerminal)->QueryInterface(IID_ITPluggableTerminalInitialization,
  282. (void **) &pTerminalInitialization);
  283. if ( FAILED(hr) )
  284. {
  285. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  286. "QueryInterface for private terminal interface failed - "
  287. "returning 0x%08x", hr));
  288. (*ppTerminal)->Release();
  289. *ppTerminal = NULL; // make buggy apps more explicitly buggy
  290. return hr;
  291. }
  292. hr = pTerminalInitialization->InitializeDynamic(iidTerminalClass,
  293. dwMediaType,
  294. Direction,
  295. htAddress);
  296. pTerminalInitialization->Release();
  297. if ( FAILED(hr) )
  298. {
  299. LOG((MSP_ERROR, "CTerminalManager::CreateDynamicTerminal - "
  300. "private Initialize() failed - "
  301. "returning 0x%08x", hr));
  302. (*ppTerminal)->Release();
  303. *ppTerminal = NULL; // make buggy apps more explicitly buggy
  304. return hr;
  305. }
  306. LOG((MSP_TRACE, "CTerminalManager::CreateDynamicTerminal - "
  307. "exit S_OK"));
  308. return S_OK;
  309. }
  310. // ITTerminalManager2
  311. STDMETHODIMP CTerminalManager::GetPluggableSuperclasses(
  312. IN OUT DWORD * pdwNumSuperclasses,
  313. OUT IID * pSuperclasses
  314. )
  315. {
  316. LOG((MSP_TRACE, "CTerminalManager::GetPluggableSuperclasses - enter"));
  317. //
  318. // Check parameters.
  319. //
  320. if ( TM_IsBadWritePtr(pdwNumSuperclasses, sizeof(DWORD) ) )
  321. {
  322. LOG((MSP_ERROR, "CTerminalManager::GetPluggableSuperclasses - "
  323. "bad NumClasses pointer - returning E_POINTER"));
  324. return E_POINTER;
  325. }
  326. //
  327. // The SafeArray VAriant for Superclasses
  328. //
  329. HRESULT hr = E_FAIL;
  330. CLSID* pSuperclassesCLSID = NULL;
  331. DWORD dwSuperclasses = 0;
  332. hr = CPTUtil::ListTerminalSuperclasses(
  333. &pSuperclassesCLSID,
  334. &dwSuperclasses
  335. );
  336. if( FAILED(hr) )
  337. {
  338. LOG((MSP_ERROR, "CTerminalManager::GetPluggableSuperclasses - "
  339. "ListTerminalSuperclasses failed - returning 0x%08x", hr));
  340. return hr;
  341. }
  342. //
  343. // If the caller is just asking for the needed buffer size, tell them.
  344. //
  345. if (pSuperclasses == NULL)
  346. {
  347. *pdwNumSuperclasses = dwSuperclasses;
  348. delete[] pSuperclassesCLSID;
  349. LOG((MSP_TRACE, "CTerminalManager::GetPluggableSuperclasses - "
  350. "provided needed buffer size - returning S_OK"));
  351. return S_OK;
  352. }
  353. //
  354. // Otherwise, the caller is asking for the terminal classes.
  355. //
  356. if ( TM_IsBadWritePtr(pSuperclasses, (*pdwNumSuperclasses) * sizeof(IID) ) )
  357. {
  358. delete[] pSuperclassesCLSID;
  359. LOG((MSP_ERROR, "CTerminalManager::GetPluggableSuperclasses - "
  360. "bad Superclasses pointer - returning E_POINTER"));
  361. return E_POINTER;
  362. }
  363. //
  364. // See if the caller gave us enough buffer space to return all the terminal
  365. // classes. If not, tell them so and stop.
  366. //
  367. if ( dwSuperclasses > *pdwNumSuperclasses )
  368. {
  369. //
  370. // Fill in the number of classes that are available.
  371. //
  372. *pdwNumSuperclasses = dwSuperclasses;
  373. delete[] pSuperclassesCLSID;
  374. LOG((MSP_ERROR, "CTerminalManager::GetPluggableSuperclasses - "
  375. "not enough space for requested info - "
  376. "returning TAPI_E_NOTENOUGHMEMORY"));
  377. return TAPI_E_NOTENOUGHMEMORY;
  378. }
  379. //
  380. // Copy the terminal classes that match this/these media type(s)
  381. // and direction(s).
  382. //
  383. for( DWORD dwSuperclass = 0; dwSuperclass < dwSuperclasses; dwSuperclass++)
  384. {
  385. pSuperclasses[dwSuperclass] = pSuperclassesCLSID[dwSuperclass];
  386. }
  387. *pdwNumSuperclasses = dwSuperclasses;
  388. // Clean-up
  389. delete[] pSuperclassesCLSID;
  390. LOG((MSP_TRACE, "CTerminalManager::GetPluggableSuperclasses - exit S_OK"));
  391. return S_OK;
  392. }
  393. STDMETHODIMP CTerminalManager::GetPluggableTerminalClasses(
  394. IN IID iidSuperclass,
  395. IN DWORD dwMediaTypes,
  396. IN OUT DWORD * pdwNumTerminals,
  397. OUT IID * pTerminals
  398. )
  399. {
  400. LOG((MSP_TRACE, "CTerminalManager::GetPluggableTerminalClasses - enter"));
  401. //
  402. // Check parameters.
  403. //
  404. if ( TM_IsBadWritePtr(pdwNumTerminals, sizeof(DWORD) ) )
  405. {
  406. LOG((MSP_ERROR, "CTerminalManager::GetPluggableTerminalClasses - "
  407. "bad NumSuperlasses pointer - returning E_POINTER"));
  408. return E_POINTER;
  409. }
  410. //
  411. // Get BSTR for iidSuperclass
  412. //
  413. if( dwMediaTypes == 0)
  414. {
  415. LOG((MSP_ERROR, "CTerminalManager::GetPluggableTerminalClasses exit -"
  416. "dwMediaTypes invalid, returns E_INVALIDARG"));
  417. return E_INVALIDARG;
  418. }
  419. if( (dwMediaTypes & (
  420. ((long)TAPIMEDIATYPE_AUDIO) |
  421. ((long)TAPIMEDIATYPE_VIDEO) |
  422. ((long)TAPIMEDIATYPE_MULTITRACK))) != dwMediaTypes )
  423. {
  424. LOG((MSP_ERROR, "CTerminalManager::GetPluggableTerminalClasses exit -"
  425. "dwMediaTypes invalid, returns E_INVALIDARG"));
  426. return E_INVALIDARG;
  427. }
  428. //
  429. // Get the object Superclass
  430. //
  431. CPTSuperclass Superclass;
  432. Superclass.m_clsidSuperclass = iidSuperclass;
  433. //
  434. // Get the terminals for this superclass
  435. //
  436. CLSID* pTerminalClasses = NULL;
  437. DWORD dwTerminalClasses = 0;
  438. HRESULT hr = E_FAIL;
  439. hr = Superclass.ListTerminalClasses(
  440. dwMediaTypes,
  441. &pTerminalClasses,
  442. &dwTerminalClasses
  443. );
  444. if( FAILED(hr) )
  445. {
  446. LOG((MSP_ERROR, "CTerminalManager::GetPluggableTerminalClasses - "
  447. "ListTerminalClasses failed - returning 0x%08x", hr));
  448. return hr;
  449. }
  450. //
  451. // If the caller is just asking for the needed buffer size, tell them.
  452. //
  453. if (pTerminals == NULL)
  454. {
  455. *pdwNumTerminals = dwTerminalClasses;
  456. delete[] pTerminalClasses;
  457. LOG((MSP_TRACE, "CTerminalManager::GetPluggableTerminalClasses - "
  458. "provided needed buffer size - "
  459. "returning S_OK"));
  460. return S_OK;
  461. }
  462. //
  463. // Otherwise, the caller is asking for the terminal classes.
  464. //
  465. if ( TM_IsBadWritePtr(pTerminals, (*pdwNumTerminals) * sizeof(IID) ) )
  466. {
  467. delete[] pTerminalClasses;
  468. LOG((MSP_ERROR, "CTerminalManager::GetPluggableTerminalClasses - "
  469. "bad TerminalClasses pointer - returning E_POINTER"));
  470. return E_POINTER;
  471. }
  472. //
  473. // See if the caller gave us enough buffer space to return all the terminal
  474. // classes. If not, tell them so and stop.
  475. //
  476. if ( dwTerminalClasses > *pdwNumTerminals )
  477. {
  478. //
  479. // Fill in the number of classes that are available.
  480. //
  481. *pdwNumTerminals = dwTerminalClasses;
  482. delete[] pTerminalClasses;
  483. LOG((MSP_ERROR, "CTerminalManager::GetPluggableTerminalClasses - "
  484. "not enough space for requested info - "
  485. "returning TAPI_E_NOTENOUGHMEMORY"));
  486. return TAPI_E_NOTENOUGHMEMORY;
  487. }
  488. //
  489. // Copy the terminal classes that match this/these media type(s)
  490. // and direction(s).
  491. //
  492. for( DWORD dwTerminal = 0; dwTerminal < dwTerminalClasses; dwTerminal++)
  493. {
  494. pTerminals[dwTerminal] = pTerminalClasses[dwTerminal];
  495. }
  496. *pdwNumTerminals = dwTerminalClasses;
  497. // Clean-up
  498. delete[] pTerminalClasses;
  499. LOG((MSP_TRACE, "CTerminalManager::GetPluggableTerminalClasses - exit S_OK"));
  500. return S_OK;
  501. }
  502. // eof