General Programming Considerations
The following considerations apply specifically to Telephony service providers (TSPs). Please also consult the main overview's General Programming Considerations section for material that covers Microsoft Telephony.
- 32 bit operation: On Windows NT/Windows 2000 platforms, a TSP must be a 32-bit component; 16-bit service providers do not run on Windows NT/Windows 2000. On the Windows 95 and Windows 98 platforms, service providers should be 32-bit components, but existing 16-bit Windows 3.1, Windows 95, and Windows 98 service providers are supported by a 16-bit thunk layer.
- List "Telephony Service" as a dependency: The installation program must include "Telephony Service" in the list of service names passed to the lpDependencies parameter of the CreateService function. When another service is activated by the telephony service provider during the service provider startup (during TSPI_providerEnumDevices, TSPI_lineNegotiateTSPIVersion, or TSPI_providerInit), this service must also be listed as a dependency of the "Telephony Service." Other functions that may be useful to a TSP in this position are QueryServiceConfig and ChangeServiceConfig.
- Support TAPI Version 2.0 or above data structures: TAPI does not provide backward compatibility for TSPs supporting only data structure formats for version 1.3 or 1.4.
- Import functions by name rather than ordinal: The performance differential, which was significant in 16-bit Windows, is very slight in 32-bit Windows and no longer justifies the relative complexity, confusion, and risk of error that is possible in requiring service providers to export TSPI functions by ordinal.
- Fully Unicode: All strings passed as parameters to TSPI functions or returned by telephony service providers in structures or through pointers must be in Unicode.
- Run in user mode: Kernel-mode components do not have direct access to TAPI services. Service provider developers can, of course, use any appropriate mechanism to access kernel mode components, should they choose to use such an architecture.
- Use the registry for storage of persistent private data: This data must 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 an application (for example, directly from a TUISPI function), but should instead pass requests back to the main service provider DLL in the TAPISRV context for synchronization and processing.
- Expose standard dynamic-link library entry point functions: TAPI will not be able to link in if these are not available.
- Report events by using TAPI-supplied callback functions.
- Run in protected mode: This requires that the PROTMODE flag must be given in the service provider module definition file (.DEF).
- Implement and export all basic telephony operations: See TSPI Basic Telephony Functions for a summary of these operations.
- Supplemental function implementation must not deviate from TAPI specifications: A TSP author may be tempted to slightly shift the intent of a function in order to suit a given need. This can result in unpredictable behavior on the part of applications attempting to use the TSP.
- Use file name extension .tsp instead of DLL: Although not a strict requirement, using this extension lets users change the service configuration by using the standard telephony control panel.
- Implement proper synchronization mechanisms on global data and resources: Because a TSP runs within the context of a Win32 process, service providers can be re-entered in the same or different functions from separate threads. 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 provides this mutex if requested by the service provider during TSPI_providerInit. TAPI is also set up so that it does not call a telephony service provider function on the same thread the telephony service provider used to call the LINEEVENT, PHONEEVENT, or ASYNC_COMPLETION callbacks in TAPI. However, it is possible for the service provider to be entered on other threads while it is executing in a TAPI callback function.
- If user interface elements are implemented, export the user interface DLL functions (prefixed by TUISPI): These can be included in a single DLL along with the TSPI functions.
Although TAPI grants simultaneous access by multiple applications to a single service provider, the service provider is not responsible for managing this access.
TAPI assigns a device identifier to each service provider. The set of device identifiers for all service providers is contiguous and non-overlapping.
TAPI performs some error checking before passing parameters to a service provider. See Error Checking for a description of tests that a telephony service provider does not need to replicate.