Resource Inventory and Version Negotiation

A line can have different capabilities. To determine these capabilities, the application should call the lineGetDevCaps function. This function fills in the LINEDEVCAPS structure, which the TSP defines. The size of the structure might be different for different service providers; therefore, the application must check to see if the buffer size is adequate. To check if the amount of space that is supplied for the structure is adequate for the size of the structure of the provider, compare the dwNeededSize and dwTotalSize parameters. If the total size is smaller than the needed size, the application must pass a larger buffer to the function.

The lineNegotiateAPIVersion function indicates the version of TAPI that the application supports, and negotiates the API version number that TAPI should use. The reason for negotiating the TAPI version is to be sure that the correct protocol is used. New versions might define new features, new fields to data structures, and so on. Version numbers, therefore, indicate how to interpret various data, structures, and messages. If version ranges do not match, the application and API or service-provider versions are incompatible, and an error is returned.

When the function succeeds, the line data, such as permanent identifier, number of addresses, and line name, can be obtained from the LINEDEVCAPS structure.

The following code example shows how to determine the capabilities of an open line.

DWORD GetLineInfo (DWORD dwLineID, LPLINEINFO lpLineInfo)
{
  DWORD dwSize,
        dwReturn;
  LPTSTR lpszLineName = NULL; 
  LPLINEDEVCAPS lpLineDevCaps = NULL;
  
  // Negotiate the API version number. If it fails, return to dwReturn.
  if (dwReturn = lineNegotiateAPIVersion (
        g_hLineApp,                   // TAPI registration handle
        dwLineID,                     // Line device to be queried
        TAPI_VERSION_1_0,             // Least recent API version 
        TAPI_CURRENT_VERSION,         // Most recent API version 
        &(lpLineInfo->dwAPIVersion),  // Negotiated API version 
        NULL))                        // Must be NULL; the provider-
                                      // specific extension is not 
                                      // supported by Windows CE.
  {
    goto exit;
  }

  dwSize = sizeof (LINEDEVCAPS);

  // Allocate enough memory for lpLineDevCaps.
  do
  {
    if (!(lpLineDevCaps = (LPLINEDEVCAPS) LocalAlloc (LPTR, dwSize)))
    {
      dwReturn = LINEERR_NOMEM;
      goto exit;
    }

    lpLineDevCaps->dwTotalSize = dwSize;

    if (dwReturn = lineGetDevCaps (g_hLineApp,
                                   dwLineID,
                                   lpLineInfo->dwAPIVersion,
                                   0,
                                   lpLineDevCaps))
    {
      goto exit;
    }

    // Stop if the allocated memory is equal to or greater than the 
    // needed memory.
    if (lpLineDevCaps->dwNeededSize <= lpLineDevCaps->dwTotalSize)
      break;  

    dwSize = lpLineDevCaps->dwNeededSize;
    LocalFree (lpLineDevCaps);
    lpLineDevCaps = NULL;
    
  } while (TRUE);

  // Store the line data in *lpLineInfo.
  lpLineInfo->dwPermanentLineID = lpLineDevCaps->dwPermanentLineID;
  lpLineInfo->dwNumOfAddress = lpLineDevCaps->dwNumAddresses;
  lpLineInfo->bVoiceLine = 
    (lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE);

  // Allocate memory for lpszLineName.
  if (!(lpszLineName = (LPTSTR) LocalAlloc (LPTR, 512)))
  {
    dwReturn = LINEERR_NOMEM;
    goto exit;
  }  
  
  // Store the line name in *lpszLineName.
  if (lpLineDevCaps->dwLineNameSize >= 512)
  {
    wcsncpy (
      lpszLineName, 
      (LPTSTR)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwLineNameOffset),
      512);
  }
  else if (lpLineDevCaps->dwLineNameSize > 0)
  {
    wcsncpy (
      lpszLineName, 
      (LPTSTR)((LPSTR)lpLineDevCaps + lpLineDevCaps->dwLineNameOffset),
      lpLineDevCaps->dwLineNameSize);
  }
  else 
    wsprintf (lpszLineName, TEXT("Line %d"), dwLineID);

  // Copy lpszLineName to lpLineInfo->lpszLineName.
  lstrcpy (lpLineInfo->szLineName, lpszLineName);

  dwReturn = ERR_NONE;

exit:
    
  if (lpLineDevCaps)
    LocalFree (lpLineDevCaps);

  if (lpszLineName)
    LocalFree (lpszLineName);

  return dwReturn; 
}

See Also

Establishing a Modem Connection | TAPI Functions | TAPI Structures

 Last updated on Saturday, April 10, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.