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.

792 lines
24 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. media.c
  5. Abstract:
  6. TAPI Service Provider functions related to media.
  7. TSPI_lineConditionalMediaDetection
  8. TSPI_lineGetID
  9. TSPI_lineMSPIdentify
  10. TSPI_lineReceiveMSPData
  11. TSPI_lineSetDefaultMediaDetection
  12. TSPI_lineSetMediaMode
  13. Environment:
  14. User Mode - Win32
  15. --*/
  16. ///////////////////////////////////////////////////////////////////////////////
  17. // //
  18. // Include files //
  19. // //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. #include "globals.h"
  22. #include "provider.h"
  23. #include "termcaps.h"
  24. #include "callback.h"
  25. #include <objbase.h>
  26. #include <initguid.h>
  27. #include "line.h"
  28. // {0F1BE7F8-45CA-11d2-831F-00A0244D2298}
  29. DEFINE_GUID(CLSID_IPMSP,
  30. 0x0F1BE7F8,0x45CA, 0x11d2, 0x83, 0x1F, 0x0, 0xA0, 0x24, 0x4D, 0x22, 0x98);
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // //
  33. // Private definitions //
  34. // //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. ///////////////////////////////////////////////////////////////////////////////
  37. // //
  38. // Private procedures //
  39. // //
  40. ///////////////////////////////////////////////////////////////////////////////
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // //
  43. // TSPI procedures //
  44. // //
  45. ///////////////////////////////////////////////////////////////////////////////
  46. LONG
  47. TSPIAPI
  48. TSPI_lineConditionalMediaDetection(
  49. HDRVLINE hdLine,
  50. DWORD dwMediaModes,
  51. LPLINECALLPARAMS const pCallParams
  52. )
  53. /*++
  54. Routine Description:
  55. If the Service Provider can monitor for the indicated set of media modes
  56. AND support the capabilities indicated in pCallParams, then it sets the
  57. indicated media moditoring modes for the line and replies with a "success"
  58. indication. Otherwise, it leaves the media monitoring modes for the line
  59. unchanged and replies with a "failure" indication.
  60. A TAPI lineOpen that specifies the device ID LINE_MAPPER typically results
  61. in calling this procedure for multiple line devices to hunt for a suitable
  62. line, possibly also opening as-yet unopened lines. A "success" result
  63. indicates that the line is suitable for the calling application's
  64. requirements. Note that the media monitoring modes demanded at the TSPI
  65. level are the union of monitoring modes demanded by multiple applications
  66. at the TAPI level. As a consequence of this, it is most common for
  67. multiple media mode flags to be set simultaneously at this level. The
  68. Service Provider should test to determine if it can support at least the
  69. specified set regardless of what modes are currently in effect.
  70. The Device ID LINE_MAPPER is never used at the TSPI level.
  71. The service provider shall return an error (e.g., LINEERR_RESOURCEUNAVAIL)
  72. if, at the time this function is called, it is impossible to place a new
  73. call on the specified line device (in other words, if it would return
  74. LINEERR_CALLUNAVAIL or LINEERR_RESOURCEUNAVAIL should TSPI_lineMakeCall be
  75. invoked immediately after opening the line).
  76. The function operates strictly synchronously.
  77. Arguments:
  78. hdLine - Specifies the Service Provider's opaque handle to the line to
  79. have media monitoring and parameter capabilities tested and set.
  80. dwMediaModes - Specifies the media mode(s) of interest to the app, of
  81. type LINEMEDIAMODE. The dwMediaModes parameter is used to register
  82. the app as a potential target for inbound call and call hand off for
  83. the specified media mode. This parameter is ignored if the OWNER flag
  84. is not set in dwPrivileges.
  85. pCallParams - Specifies a far pointer to a structure of type
  86. LINECALLPARAMS. It describes the call parameters that the line device
  87. should be able to provide.
  88. Return Values:
  89. Returns zero if the function is successful, or a negative error number if
  90. an error has occurred. Possible error returns are:
  91. LINEERR_INVALADDRESSMODE - The address mode is invalid.
  92. LINEERR_INVALBEARERMODE - The bearer mode is invalid.
  93. LINEERR_INVALLINEHANDLE - The specified line handle is invalid.
  94. LINEERR_INVALMEDIAMODE - One or more media modes specified as a
  95. parameter or in a list is invalid or not supported by the the
  96. service provider.
  97. LINEERR_RESOURCEUNAVAIL - The specified operation cannot be completed
  98. because of resource overcommitment.
  99. --*/
  100. {
  101. PH323_LINE pLine = NULL;
  102. // see if we support media modes specified
  103. if (dwMediaModes & ~H323_LINE_MEDIAMODES) {
  104. H323DBG((
  105. DEBUG_LEVEL_ERROR,
  106. "do not support media modes 0x%08lx.\n",
  107. dwMediaModes
  108. ));
  109. // do not support media mode
  110. return LINEERR_INVALMEDIAMODE;
  111. }
  112. // validate pointer
  113. if (pCallParams != NULL) {
  114. // see if we support media modes specified
  115. if (pCallParams->dwMediaMode & ~H323_LINE_MEDIAMODES) {
  116. H323DBG((
  117. DEBUG_LEVEL_ERROR,
  118. "do not support media modes 0x%08lx.\n",
  119. pCallParams->dwMediaMode
  120. ));
  121. // do not support media mode
  122. return LINEERR_INVALMEDIAMODE;
  123. }
  124. // see if we support bearer modes
  125. if (pCallParams->dwBearerMode & ~H323_LINE_BEARERMODES) {
  126. H323DBG((
  127. DEBUG_LEVEL_ERROR,
  128. "do not support bearer mode 0x%08lx.\n",
  129. pCallParams->dwBearerMode
  130. ));
  131. // do not support bearer mode
  132. return LINEERR_INVALBEARERMODE;
  133. }
  134. // see if we support address modes
  135. if (pCallParams->dwAddressMode & ~H323_LINE_ADDRESSMODES) {
  136. H323DBG((
  137. DEBUG_LEVEL_ERROR,
  138. "do not support address mode 0x%08lx.\n",
  139. pCallParams->dwAddressMode
  140. ));
  141. // do not support address mode
  142. return LINEERR_INVALADDRESSMODE;
  143. }
  144. }
  145. // retrieve line device pointer from handle
  146. if (!H323GetLineAndLock(&pLine, hdLine)) {
  147. // invalid line device handle
  148. return LINEERR_INVALLINEHANDLE;
  149. }
  150. // see if line is available
  151. if (!H323IsLineAvailable(pLine)) {
  152. H323DBG((
  153. DEBUG_LEVEL_ERROR,
  154. "line %d is currently at maximum capacity.\n",
  155. pLine->dwDeviceID
  156. ));
  157. // release line device
  158. H323UnlockLine(pLine);
  159. // no addresses available
  160. return LINEERR_RESOURCEUNAVAIL;
  161. }
  162. // release line device
  163. H323UnlockLine(pLine);
  164. // success
  165. return NOERROR;
  166. }
  167. LONG
  168. TSPIAPI
  169. TSPI_lineGetID(
  170. HDRVLINE hdLine,
  171. DWORD dwAddressID,
  172. HDRVCALL hdCall,
  173. DWORD dwSelect,
  174. LPVARSTRING pDeviceID,
  175. LPCWSTR pwszDeviceClass,
  176. HANDLE hTargetProcess
  177. )
  178. /*++
  179. Routine Description:
  180. This function returns a device ID for the specified device class
  181. associated with the selected line, address or call.
  182. This function can be used to retrieve a line device ID given a
  183. line handle. Although the TAPI DLL has sufficient information to
  184. determine the line device ID from a line handle, it may still call
  185. this operation in such a fashion on behalf of an application that
  186. has opened a line device using LINE_MAPPER. The Service Provider
  187. should support the "line" device class to allow applications to
  188. determine the real line device ID of an opened line.
  189. This function can also be used to obtain the device ID of a phone
  190. device or media device (e.g., mci waveform, mci midi, wave, fax,
  191. etc.) associated with a call, address or line. This ID can then be
  192. used with the appropriate API (e.g., phone, mci, midi, wave, etc.)
  193. to select the corresponding media device associated with the specified
  194. call.
  195. Note that the notion of Windows device class is different from that of
  196. media mode. For example, the interactive voice or stored voice media
  197. modes may be accessed using either the mci waveaudio or the low level
  198. wave device classes. A media modes describes a format of information
  199. on a call, a device class defines a Windows API used to manage that
  200. stream. Often, a single media stream may be accessed using multiple
  201. device classes, or a single device class (e.g., the Windows COMM API)
  202. may provide access to multiple media modes.
  203. Note that a new device class value is defined in TAPI 2.0:
  204. "comm/datamodem/portname"
  205. When TSPI_lineGetID is called specifying this device class on a line
  206. device that supports the class, the VARSTRING structure returned will
  207. contain a null-terminated ANSI (not UNICODE) string specifying the name
  208. of the port to which the specified modem is attached, such as "COM1\0".
  209. This is intended primarily for identification purposes in user interface,
  210. but could be used under some circumstances to open the device directly,
  211. bypassing the service provider (if the service provider does not already
  212. have the device open itself). If there is no port associated with the
  213. device, a null string ("\0") is returned in the VARSTRING structure (with
  214. a string length of 1).
  215. Arguments:
  216. hdLine - Specifies the Service Provider's opaque handle to the line
  217. to be queried.
  218. dwAddressID - Specifies an address on the given open line device.
  219. hdCall - Specifies the Service Provider's opaque handle to the call
  220. to be queried.
  221. dwSelect - Specifies the whether the device ID requested is associated
  222. with the line, address or a single call, of type LINECALLSELECT.
  223. pDeviceID - Specifies a far pointer to the memory location of type
  224. VARSTRING where the device ID is returned. Upon successful completion
  225. of the request, this location is filled with the device ID. The
  226. format of the returned information depends on the method used by the
  227. device class (API) for naming devices.
  228. pwszDeviceClass - Specifies a far pointer to a NULL-terminated ASCII
  229. string that specifies the device class of the device whose ID is
  230. requested. Valid device class strings are those used in the SYSTEM.INI
  231. section to identify device classes.
  232. hTargetProcess - The process handle of the application on behalf of which
  233. the TSPI_lineGetID function is being invoked. If the information being
  234. returned in the VARSTRING structure includes a handle for use by the
  235. application, the service provider should create or duplicate the handle
  236. for the process.
  237. If hTargetProcess is set to INVALID_HANDLE_VALUE, then the application
  238. is executing on a remote client system and it is not possible to create
  239. a duplicate handle directly. Instead, the VARSTRING structure should
  240. contain a UNC name of a network device or other name that the remote
  241. client can use to access the device. If this is not possible, then the
  242. function should fail.
  243. Return Values:
  244. Returns zero if the function is successful or a negative error
  245. number if an error has occurred. Possible error returns are:
  246. LINEERR_INVALCALLHANDLE - The hdCall parameter is an invalid handle.
  247. LINEERR_INVALCALLSELECT - The specified dwCallSelect parameter is
  248. invalid.
  249. LINEERR_INVALCALLSTATE - One or more of the specified calls are not in
  250. a valid state for the requested operation.
  251. LINEERR_NODEVICE - The line device has no associated device for the
  252. given device class.
  253. LINEERR_STRUCTURETOOSMALL - The dwTotalSize member of a structure does
  254. not specify enough memory to contain the fixed portion of the
  255. structure. The dwNeededSize field has been set to the amount
  256. required.
  257. --*/
  258. {
  259. // do not support device
  260. return LINEERR_NODEVICE;
  261. }
  262. LONG
  263. TSPIAPI
  264. TSPI_lineMSPIdentify(
  265. DWORD dwDeviceID,
  266. GUID * pCLSID
  267. )
  268. /*++
  269. Routine Description:
  270. This procedure is called after TAPI has initialized the line device in
  271. order to determine the assoicated Media Service Provider.
  272. Arguments:
  273. dwDeviceID - Identifies the line device to be opened. The value
  274. LINE_MAPPER for a device ID is not permitted.
  275. pCLSID - Points to a GUID-sized memory location which the service
  276. provider writes the class identifier of the associated media
  277. service provider.
  278. Return Values:
  279. Returns zero if the function is successful or a negative error
  280. number if an error has occurred. Possible error returns are:
  281. LINEERR_BADDEVICEID - The specified line device ID is out of range.
  282. LINEERR_OPERATIONFAILED - The operation failed for an unspecified or
  283. unknown reason.
  284. --*/
  285. {
  286. PH323_LINE pLine = NULL;
  287. // retrieve pointer to line device from device id
  288. if (!H323GetLineFromIDAndLock(&pLine, dwDeviceID)) {
  289. // do not recognize device
  290. return LINEERR_BADDEVICEID;
  291. }
  292. // copy class id
  293. *pCLSID = CLSID_IPMSP;
  294. // release line device
  295. H323UnlockLine(pLine);
  296. // success
  297. return NOERROR;
  298. }
  299. LONG
  300. TSPIAPI
  301. TSPI_lineReceiveMSPData(
  302. HDRVLINE hdLine,
  303. HDRVCALL hdCall,
  304. HDRVMSPLINE hdMSPLine,
  305. LPVOID pBuffer,
  306. DWORD dwSize
  307. )
  308. /*++
  309. Routine Description:
  310. This procedure is called to deliver a payload from the MSP.
  311. Arguments:
  312. hdCall - Handle to line object.
  313. hdCall - Handle to call object associated with MSP.
  314. hdMSPLine - Handle to MSP.
  315. pBuffer - Pointer to opaque buffer with MSP data.
  316. dwSize - Size of buffer above.
  317. Return Values:
  318. Returns zero if the function is successful or a negative error
  319. number if an error has occurred. Possible error returns are:
  320. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  321. LINEERR_OPERATIONFAILED - The operation failed for an unspecified or
  322. unknown reason.
  323. --*/
  324. {
  325. PH323_CALL pCall = NULL;
  326. PH323MSP_MESSAGE pMessage = (PH323MSP_MESSAGE)pBuffer;
  327. // validate pointer and message size
  328. if ((pMessage == NULL) || (dwSize != sizeof(H323MSP_MESSAGE))) {
  329. // could not cancel listen
  330. return LINEERR_OPERATIONFAILED;
  331. }
  332. // see if call handle is valid
  333. if (!H323GetCallAndLock(&pCall, hdCall)) {
  334. // see if this is a line message.
  335. switch (pMessage->Type) {
  336. case H323MSP_CONFIG_T120_COMMAND:
  337. H323LockProvider();
  338. H323ProcessConfigT120Command(
  339. &pMessage->ConfigT120Command
  340. );
  341. H323UnlockProvider();
  342. break;
  343. case H323MSP_CONFIG_CAPABILITY_COMMAND:
  344. H323LockProvider();
  345. H323ProcessConfigCapabilityCommand(
  346. &pMessage->ConfigCapabilityCommand
  347. );
  348. H323UnlockProvider();
  349. break;
  350. case H323MSP_SET_ALIAS_COMMAND:
  351. H323LockProvider ();
  352. if (pMessage->SetAliasCommand.dwLength > 0)
  353. {
  354. // check pointer
  355. if (IsBadReadPtr (
  356. pMessage->SetAliasCommand.strAlias,
  357. pMessage->SetAliasCommand.dwLength * sizeof (WCHAR)
  358. ))
  359. {
  360. H323DBG((
  361. DEBUG_LEVEL_ERROR,
  362. "H323MSP_SET_ALIAS_COMMAND receives bad pointer"
  363. ));
  364. break;
  365. }
  366. // check wcs length
  367. g_dwAliasLength = pMessage->SetAliasCommand.dwLength < MAX_ALIAS_LENGTH
  368. ?pMessage->SetAliasCommand.dwLength
  369. :MAX_ALIAS_LENGTH;
  370. // copy
  371. CopyMemory (
  372. g_strAlias,
  373. pMessage->SetAliasCommand.strAlias,
  374. g_dwAliasLength * sizeof (WCHAR)
  375. );
  376. // end char
  377. g_strAlias[g_dwAliasLength] = L'\0';
  378. }
  379. H323UnlockProvider ();
  380. break;
  381. default:
  382. // invalid call handle
  383. return LINEERR_INVALCALLHANDLE;
  384. }
  385. // success
  386. return NOERROR;
  387. }
  388. switch (pMessage->Type) {
  389. case H323MSP_OPEN_CHANNEL_REQUEST:
  390. H323ProcessOpenChannelRequest(
  391. pCall,
  392. &pMessage->OpenChannelRequest
  393. );
  394. break;
  395. case H323MSP_ACCEPT_CHANNEL_RESPONSE:
  396. H323ProcessAcceptChannelResponse(
  397. pCall,
  398. &pMessage->AcceptChannelResponse
  399. );
  400. break;
  401. case H323MSP_CLOSE_CHANNEL_COMMAND:
  402. H323ProcessCloseChannelCommand(
  403. pCall,
  404. &pMessage->CloseChannelCommand
  405. );
  406. break;
  407. case H323MSP_VIDEO_FAST_UPDATE_PICTURE_COMMAND:
  408. H323ProcessVideoFastUpdatePictureCommand(
  409. pCall,
  410. &pMessage->VideoFastUpdatePictureCommand
  411. );
  412. break;
  413. case H323MSP_FLOW_CONTROL_COMMAND:
  414. H323ProcessFlowControlCommand(
  415. pCall,
  416. &pMessage->FlowControlCommand
  417. );
  418. break;
  419. case H323MSP_QOS_Evnet:
  420. H323ProcessQoSEventIndication(
  421. pCall,
  422. &pMessage->QOSEvent
  423. );
  424. break;
  425. }
  426. // unlock line device
  427. H323UnlockLine(pCall->pLine);
  428. // success
  429. return NOERROR;
  430. }
  431. LONG
  432. TSPIAPI
  433. TSPI_lineSetDefaultMediaDetection(
  434. HDRVLINE hdLine,
  435. DWORD dwMediaModes
  436. )
  437. /*++
  438. Routine Description:
  439. This procedure tells the Service Provider the new set of Media Modes to
  440. detect for the indicated line (replacing any previous set). It also sets
  441. the initial set of Media Modes that should be monitored for on subsequent
  442. calls (inbound or outbound) on this line.
  443. The TAPI DLL typically calls this function to update the set of detected
  444. media modes for the line to the union of all modes selected by all
  445. outstanding lineOpens whenever a line is Opened or Closed at the TAPI
  446. level. A lineOpen attempt is rejected if media detection is rejected.
  447. A single call to this procedure is typically the result of a lineOpen
  448. that does not specify the device ID LINE_MAPPER. The Device ID LINE_MAPPER
  449. is never used at the TSPI level.
  450. Arguments:
  451. hdLine - Specifies the Service Provider's opaque handle to the line to
  452. have media monitoring set.
  453. dwMediaModes - Specifies the media mode(s) of interest to the TAPI DLL,
  454. of type LINEMEDIAMODE.
  455. Return Values:
  456. Returns zero if the function is successful or a negative error
  457. number if an error has occurred. Possible error returns are:
  458. LINEERR_INVALLINEHANDLE - The specified line handle is invalid.
  459. LINEERR_INVALMEDIAMODE - One or more media modes specified as a
  460. parameter or in a list is invalid or not supported by the the
  461. service provider.
  462. --*/
  463. {
  464. HRESULT hr;
  465. PH323_LINE pLine = NULL;
  466. // see if unknown bit is specified
  467. if (dwMediaModes & LINEMEDIAMODE_UNKNOWN) {
  468. H323DBG((
  469. DEBUG_LEVEL_VERBOSE,
  470. "clearing unknown media mode.\n"
  471. ));
  472. // clear unknown bit from modes
  473. dwMediaModes &= ~LINEMEDIAMODE_UNKNOWN;
  474. }
  475. // see if both audio bits are specified
  476. if ((dwMediaModes & LINEMEDIAMODE_AUTOMATEDVOICE) &&
  477. (dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE)) {
  478. H323DBG((
  479. DEBUG_LEVEL_VERBOSE,
  480. "clearing automated voice media mode.\n"
  481. ));
  482. // clear extra audio bit from modes
  483. dwMediaModes &= ~LINEMEDIAMODE_INTERACTIVEVOICE;
  484. }
  485. // see if we support media modes specified
  486. if (dwMediaModes & ~H323_LINE_MEDIAMODES) {
  487. H323DBG((
  488. DEBUG_LEVEL_ERROR,
  489. "do not support media modes 0x%08lx.\n",
  490. dwMediaModes
  491. ));
  492. // do not support media mode
  493. return LINEERR_INVALMEDIAMODE;
  494. }
  495. // retrieve line device pointer from handle
  496. if (!H323GetLineAndLock(&pLine, hdLine)) {
  497. // invalid line device handle
  498. return LINEERR_INVALLINEHANDLE;
  499. }
  500. H323DBG((
  501. DEBUG_LEVEL_TRACE,
  502. "line %d enabled to detect media modes 0x%08lx.\n",
  503. pLine->dwDeviceID,
  504. dwMediaModes
  505. ));
  506. // record media modes to detect
  507. pLine->dwMediaModes = dwMediaModes;
  508. // see if we need to start listening
  509. if (H323IsMediaDetectionEnabled(pLine) &&
  510. !H323IsListening(pLine) &&
  511. !H323StartListening(pLine)) {
  512. // release line device
  513. H323UnlockLine(pLine);
  514. // could not cancel listen
  515. return LINEERR_OPERATIONFAILED;
  516. // see if we need to stop listening
  517. } else if (H323IsListening(pLine) &&
  518. !H323IsMediaDetectionEnabled(pLine) &&
  519. !H323StopListening(pLine)) {
  520. // release line device
  521. H323UnlockLine(pLine);
  522. // could not cancel listen
  523. return LINEERR_OPERATIONFAILED;
  524. }
  525. // release line device
  526. H323UnlockLine(pLine);
  527. // success
  528. return NOERROR;
  529. }
  530. LONG
  531. TSPIAPI
  532. TSPI_lineSetMediaMode(
  533. HDRVCALL hdCall,
  534. DWORD dwMediaMode
  535. )
  536. /*++
  537. Routine Description:
  538. This function changes the call's media as stored in the call's
  539. LINECALLINFO structure.
  540. Other than changing the call's media as stored in the call's
  541. LINECALLINFO structure, this procedure is simply "advisory" in the sense
  542. that it indicates an expected media change that is about to occur, rather
  543. than forcing a specific change to the call. Typical usage is to set a
  544. calls media mode to a specific known media mode, or to exclude possible
  545. media modes as long as the call's media mode is not fully known; i.e.,
  546. the UNKNOWN media mode flag is set.
  547. Arguments:
  548. hdCall - Specifies the Service Provider's opaque handle to the call
  549. undergoing a change in media mode. Valid call states: any.
  550. dwMediaMode - Specifies the new media mode(s) for the call, of type
  551. LINEMEDIAMODE. As long as the UNKNOWN media mode flag is set,
  552. multiple other media mode flags may be set as well. This is used
  553. to indentify a call's media mode as not fully determined, but
  554. narrowed down to one of just a small set of specified media modes.
  555. If the UNKNOWN flag is not set, then only a single media mode can
  556. be specified.
  557. Return Values:
  558. Returns zero if the function is successful or a negative error
  559. number if an error has occurred. Possible error returns are:
  560. LINEERR_INVALCALLHANDLE - The specified call handle is invalid.
  561. LINEERR_INVALMEDIAMODE - The specified media mode parameter is invalid.
  562. LINEERR_OPERATIONUNAVAIL - The specified operation is not available.
  563. LINEERR_OPERATIONFAILED - The specified operation failed for
  564. unspecified reasons.
  565. --*/
  566. {
  567. return LINEERR_OPERATIONUNAVAIL; // CODEWORK...
  568. }