Toby Nixon, Program Manager
Windows Telephony, Microsoft Corporation
June 1996
Microsoft® Windows NT® 4.0 includes version 2.0 of the Windows® Telephony API (TAPI 2.0). This article provides an overview of TAPI 2.0, with particular focus on the requirements for telephony service providers (drivers) that are likely to be implemented by independent hardware vendors (IHVs).
Microsoft® Windows® Telephony API (TAPI) version 2.0 brings the full functionality of TAPI version 1.4 from Microsoft Windows 95 to Windows NT® as a Win32® service. All core TAPI 2.0 components are Win32-based, with full support for RISC-based processors, symmetrical multiprocessing, multithreaded applications, and preemptive multitasking. Support for call center management is enhanced, with modeling of predictive dialing ports and queues, ACD agent control, associating data with calls, controlling music on hold and other call treatments, controlling message waiting lights, and centralized event timing. Among other enhancements, applications can request, negotiate, and renegotiate quality of service (QOS) (performance) parameters with the network, and receive indication of QOS on inbound calls and when QOS is changed by the network (the QOS structures are binary-compatible with those used in the Windows Sockets 2.0 specification). As with previous versions of TAPI, the availability of these features depends upon the underlying telephony service provider and hardware.
Existing Win32-based full TAPI and assisted TAPI applications that run on Windows 95 (using TAPI 1.4 functions) will run on Windows NT on x86 processors without modification or recompilation. Existing 16-bit full TAPI and assisted TAPI applications that run on Windows 95 and Windows 3.1 (using the TAPI 1.3 API) will also run on Windows NT. Win32-based applications can choose to either call the existing TAPI functions that use ANSI strings or call Unicode versions of functions that pass or return strings (functions with a "W" suffix). TAPI 2.0 adds mechanisms for notifying applications of telephony events that do not require the application to have a window message queue, thereby enabling background service processes to easily use TAPI services.
Figure 1 shows, at a very high level, the general architecture of TAPI 2.0. The Universal Modem Driver (Unimodem) is shown as an example of a service provider implementation.
Figure 1. General architecture of TAPI 2.0
Existing 16-bit TAPI applications link to Tapi.dll. In Windows 3.1 and Windows 95, Tapi.dll was the core of Windows Telephony, but in Windows NT, Tapi.dll is simply a thunk layer used to map 16-bit addresses to 32-bit addresses and pass requests along to Tapi32.dll.
Existing 32-bit TAPI applications link to Tapi32.dll. In Windows 95, Tapi32.dll was a thunk layer to Tapi.dll. In Windows NT, Tapi32.dll is a marshaling layer that uses lightweight remote procedure call (LRPC) technology to transfer function requests to Tapisrv.exe and, when needed, loads and invokes service-provider user-interface DLLs in the application's process.
Tapisrv.exe is now the core of TAPI. It runs as a separate service process, subsuming the role played in Windows 3.1 and Windows 95 by the Tapiexe.exe hidden process and Tapi.dll itself. All telephony service providers execute in the Tapisrv executable's process, eliminating the difficulties that arose in previous versions of Windows Telephony, caused by service providers sometimes running in Tapiexe's context and sometimes in the context of an individual application. Service providers can create threads in Tapisrv's context as needed to do their work and be confident that none of the resources they create will be destroyed by the exiting of any individual application.
Underneath the service provider DLL (TSP), the service provider can use any system functions or other components necessary, including CreateFile and DeviceIOControl, to work with IHV-designed kernel mode components and services as well as standard devices such as serial and parallel ports to control external locally attached devices. They can also access network services (such as RPC, WinSockets, and named pipes) for client-server telephony.
In addition to these new components, two other types of new components can exist in a TAPI 2.0 system. The first is the telephony service-provider user-interface DLL, which is explained in detail below. The second new component type is known generically as a proxy request handler. A proxy request handler is a full telephony application that normally executes on a telephony server (the same server on which the telephony service provider is executing for the associated line devices). This architecture, rather than the WOSA "service provider" architecture, is used when a particular service is more appropriately implemented in an application than a driver on the server. In this version of TAPI, the ACD agent management functions would be implemented in a proxy request handler rather than in a service provider.
Windows Telephony for Windows NT 4.0 includes a generic kernel-mode telephony service-provider interface (TSPI) mapper, known as KMDDSP, that allows service providers to be implemented as kernel-mode device drivers. The existing support in Windows NT 3.5 for ISDN WAN miniports under Remote Access Service is preserved. NDIS WAN miniport drivers will be supported under the kernel-mode service provider without modification.
The Unimodem service provider will be available on Windows NT 4.0 as well, with greatly improved performance, support for large installations of modems (for example, for RAS servers), and many more modem definitions. However, the voice features of Unimodem/V, which shipped several months after the first release of Windows 95, will not be available in the initial release of Windows NT 4.0.
Under TAPI 2.0, a telephony service provider consists of, at a minimum, a Win32 DLL that executes in user mode in the Tapisrv process; 16-bit service providers from Windows 3.1 and Windows 95 will not run on Windows NT under TAPI 2.0. A TSP DLL can create threads and synchronization objects within Tapisrv's context.
Because they are running within the context of a Win32 process, service providers can be re-entered in the same or different functions from separate threads. The service provider must be designed with proper synchronization mechanisms on global data and resources. For performance reasons, implementers are discouraged from requiring a single "master" mutex on the entire service provider, although such a mechanism can be advantageous during an interim period while porting 16-bit service provider code; TAPI will provide this mutex if requested by the service provider during TSPI_providerInit. TAPI is also designed such that it will not call a TSP function on the same thread that the TSP used to call the LINEEVENT, PHONEEVENT, or ASYNC_COMPLETION callbacks in TAPI, but it is possible for the service provider to be entered on other threads while it is executing in a TAPI callback function.
Service providers for use with TAPI 2.0 must support at least TSPI version 0x00020000, including all data structure fields. TAPI will not adapt older service providers to work with newer applications.
Except as noted in the TAPI 2.0 documentation, all strings passed into or returned by service provider functions (as function parameters or structure fields) must be Unicode.
In accordance with Win32 standards, all TSPI functions are imported by Tapisrv by name, rather than by ordinal, as was the practice in previous 16-bit implementations. The performance differential, which was significant in 16-bit Windows, is very slight with Win32 and no longer justifies the relative complexity, confusion, and risk of error of requiring service providers to export TSPI functions by ordinal.
TAPI no longer uses the Telephon.ini file for storage of telephony parameters. Service providers, like all Win32 services, should use the registry for storage of persistent private data. This data should not be placed in TAPI's section of the registry, the format of which is not guaranteed to be maintained in future versions. Service providers should create their own branch under the "Software" key. Service providers should not directly access their registry parameters from within the context of application (that is, directly from a TUISPI_ function), but should instead pass requests back to the main service provider DLL in TAPISRV's context for synchronization and processing.
The components of TAPI use various interprocess communications mechanisms to convey function requests and messages between applications and service providers. The applications and the service providers can be executing not only in separate processes but also on completely separate systems. Service providers, therefore, cannot display dialog boxes in the process or even on the machine on which they are executing; the user interface must be invoked from within the application context, on the machine on which the application is executing.
This section defines the mechanism by which service-provider user-interface (UI) functions are loaded and invoked within the application context. A mechanism is also defined by which service providers can spontaneously open dialog boxes in the application context when they would not otherwise be expected by the application. An example of this latter case would be the "Talk/Hang-up" dialog box that is displayed by data modem service providers when the modem is being used as a dialer for interactive voice calls and the user must be told to pick up the phone and inform the service provider when to place the modem "on hook."
Figure 2. Architecture of telephony service providers and their UI DLLs
Figure 2 shows the general architecture of telephony service providers and their associated user-interface dynamic-link libraries (UI DLLs). The service provider consists of a minimum of two components. The main service-provider DLL (designated in the diagram as "Main.tsp") executes in the context of the TAPI service and performs all of the tasks of the service provider that are not related to user-interface elements associated with a particular application's use of the device (most likely, in conjunction with lower-level components not shown in the diagram). But unlike previous versions of TAPI in which the user interface code was integrated into the main service provider (and executed, because of the previous architecture, within the context of the application), the service provider must now include a separate component that implements the user-interface elements.
The service-provider UI DLL must be a Win32 DLL. It must export functions that are called by Tapi32.dll when the application calls TAPI functions that generate UI. Each of these functions includes as a parameter a pointer to a callback function in Tapi32.dll that the UI DLL can use to communicate bidirectionally (both send and receive data) with the main TSP DLL executing in Tapisrv's process. If the service provider ever generates "spontaneous" UI, such as the Unimodem or ATSP Talk/Hangup dialog box, in conjunction with any TSPI function for which UI is not expected (that is, any function that does not have an "hwnd" parameter), then the UI DLL must export additional functions used to create and convey data to the spontaneous dialog box. The main service provider DLL must export a function that TAPISRV uses to obtain the name of the UI DLL to load in the application process, as well as a few additional housekeeping entry points. All of the TUISPI functions are described in detail in the TAPI section of the Platform SDK.
The names of the TSPI functions and the TUISPI functions are intentionally defined to be different, so it is possible for the main TSP DLL and the UI DLL to be the same DLL file, if desired. With proper segmentation, this would not necessarily result in any unnecessary use of memory in the application context and would simplify the installation process for service providers that can currently be implemented in a single DLL. TAPI32 and Tapisrv will call only the functions that are appropriate for the context in which the DLL is being used.
The main TSP and the UI DLL must both be designed with the requirement in mind that the UI functions may be invoked from multiple application processes simultaneously. They must also consider that the application and the TAPI service under which the main TSP is executing may be on separate computers on a LAN (TAPI32 and Tapisrv cooperate to load the UI DLL across the LAN, if necessary).
Technical support for development of telephony service providers is available through Microsoft AnswerPoint Developer Support. When you call, be sure to mention that you are working on a "TAPI Service Provider" so that your call is routed to developer support engineers knowledgeable in this area.
The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.
This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS DOCUMENT.