⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enumtapi.c

📁 列出当前所有的tapi设备
💻 C
字号:
/*-------------------------------------------------*\

EnumTapi is a sample console app that enumerates all the devices 
made available by TAPI and prints relavent information on each one.

Whether a line is actually capable of datamodem or automatedvoice
depends on what specific capabilities are used by a specific application.
The checks made by this sample are fairly generic, so they aren't a 
guarentee that a specific app will work.

This app could very easily be tailored to check the needs of any specific
application.  Might make a very simple but very usefull tech-support tool.

This app will only run with TAPI API Version 1.4 or later.  
This means Windows 95 or later versions of TAPI.

This is version 1.0 of this sample.  It is very likely going to change
when it is released into the Microsoft Sample Library.

\*-------------------------------------------------*/


#include <windows.h>
#include <tapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char szAppName[] = "TapiTest";

// TAPI global variables.
HINSTANCE hInstance;
HLINEAPP hLineApp;
DWORD dwNumDevs;
long lReturn;

VARSTRING SmallVarString;
LINEDEVSTATUS LineDevStatus;
LPLINEDEVCAPS lpLineDevCaps = NULL;

LPLINEPROVIDERLIST lpLineProviderList = NULL;
LPLINEPROVIDERENTRY lpLineProviderEntry;

char szLineUnavail[]   = "Line Unavailable";
char szLineUnnamed[]   = "Line Unnamed";
char szLineNameEmpty[] = "Line Name is Empty";


void CALLBACK lineCallbackFunc(
    DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, 
    DWORD dwParam1, DWORD dwParam2, DWORD dwParam3);
void PrintTapiLines(DWORD dwDeviceID);
char * FormatLineError (long lError);

int main (int argc, char * argv[], char * envp[])
{
   MSG msg;
   DWORD i;

   // Prime the message queue
   PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

   hInstance = GetModuleHandle(NULL);

   if (lReturn = lineInitialize(&hLineApp, hInstance, lineCallbackFunc, 
      szAppName, &dwNumDevs))
   {
      printf("lineInitialize failed: %s.\n", FormatLineError(lReturn));
      return 0;
   }

   lpLineDevCaps      = LocalAlloc(LPTR, 4096);
   lpLineProviderList = LocalAlloc(LPTR, 4096);
   lpLineDevCaps     -> dwTotalSize = 4096;
   lpLineProviderList-> dwTotalSize = 4096;
   LineDevStatus      . dwTotalSize = sizeof(LineDevStatus);
   SmallVarString     . dwTotalSize = sizeof(SmallVarString);

   // Get the Provider List so its possible to associate a line device
   // with a specific service provider later.
   while(TRUE)
   {
      lReturn = lineGetProviderList(0x00010004, lpLineProviderList);
      if (lReturn)
      {
         printf("lineGetProviderList failed: %s\n", FormatLineError(lReturn));
         goto end;
      }

      if (lpLineProviderList->dwNeededSize > lpLineProviderList->dwTotalSize)
      {
         lpLineProviderList = 
            LocalReAlloc(lpLineProviderList, 
               lpLineProviderList->dwNeededSize, LMEM_MOVEABLE);
         lpLineProviderList->dwTotalSize = lpLineProviderList->dwNeededSize;
         continue;
      }

      lpLineProviderEntry = (LPLINEPROVIDERENTRY)
         ((BYTE *) lpLineProviderList + 
            lpLineProviderList->dwProviderListOffset);
      break;
   }

   if (dwNumDevs)
   {
      printf(
         "<- dwDeviceID\n"
         "|   <- Max dwAPIVersion\n"
         "|   |    <- dwNumAddresses\n"
         "|   |    |  <- dwPermanentLineID\n"
         "|   |    |  |            <- Capable of making voice comm/datamodem calls?\n"
         "|   |    |  |            |  <- Capable of making automated voice calls?\n"
         "|   |    |  |            |  |  <- Call in progress?\n"
         "|   |    |  |            |  |  |  <- Any application waiting for calls?\n"
         "|   |    |  |            |  |  |  |  <- Service Povider - Line Device Name\n"
         "V   V    V  V            V  V  V  V\n"
         );
      for (i=0;i<dwNumDevs;i++)
      {
         PrintTapiLines(i);
      }
   }
   else
      printf("No TAPI Line devices installed.\n");

 end:

   lineShutdown(hLineApp);
   LocalFree(lpLineDevCaps);
   LocalFree(lpLineProviderList);
}

void PrintTapiLines(DWORD dwDeviceID)
{
   BOOL bSupportsDataComm = TRUE;
   BOOL bSupportsAutomatedVoice = TRUE;

   DWORD dwApiVersion;
   LINEEXTENSIONID ExtensionID;
   HLINE hLine;
   DWORD dwAddressID = 0;
   char * lpszLineName;
   DWORD dwCount;

   printf("%-2lu, ", dwDeviceID);

   // Find the max API Version supported.
   // Note that this is normally a bad thing to do!!!
   // Usually, you use an API Version that you know your app can support.
   lReturn = lineNegotiateAPIVersion (hLineApp, dwDeviceID,
      0x00010003, 0x0FFF0FFF, &dwApiVersion, &ExtensionID);

   if (lReturn)
   {
      printf("lineNegotiateAPIVersion error: %s\n", FormatLineError(lReturn));
      return;
   }

   printf("%lx.%lx, ", (dwApiVersion&0xFFFF0000)/0x00010000, 
      dwApiVersion&0x0000FFFF);

   lReturn = lineNegotiateAPIVersion (hLineApp, dwDeviceID,
      0x00010004, 0x00010004, &dwApiVersion, &ExtensionID);

   if (lReturn)
   {
      if (lReturn == LINEERR_INCOMPATIBLEAPIVERSION)
         printf("Doesn't support API Version 1.4\n");
      else
         printf("lineNegotiateAPIVersion error: %s\n", FormatLineError(lReturn));
      return;
   }

   while(TRUE)
   {
      lReturn = lineGetDevCaps(hLineApp, dwDeviceID, 
         dwApiVersion, 0, lpLineDevCaps);

      if (lReturn)
      {
         printf("lineGetDevCaps error: %s\n", FormatLineError(lReturn));
         return;
      }

      if (lpLineDevCaps->dwNeededSize > lpLineDevCaps->dwTotalSize)
      {
         lpLineDevCaps = 
            LocalReAlloc(lpLineDevCaps, 
               lpLineDevCaps->dwNeededSize, LMEM_MOVEABLE);
         lpLineDevCaps->dwTotalSize = lpLineDevCaps->dwNeededSize;
         continue;
      }
      
      break;
   }

   // Print number of available addresses..
   printf("%lu, ", lpLineDevCaps->dwNumAddresses);

   // Print permanent line ID
   printf("0x%08lX, ", lpLineDevCaps->dwPermanentLineID);

   // Check to see if basic data/voice capabilities are available.
   if (!(lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE ))
      bSupportsDataComm = FALSE;

   if (!((lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE ) ||
         (lpLineDevCaps->dwBearerModes & LINEBEARERMODE_SPEECH )))
      bSupportsAutomatedVoice = FALSE;

   if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM))
      bSupportsDataComm = FALSE;

   if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_AUTOMATEDVOICE))
      bSupportsAutomatedVoice = FALSE;

   // Make sure it is possible to make a call.
   if (!(lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL))
   {
      bSupportsDataComm = FALSE;
      bSupportsAutomatedVoice = FALSE;
   }

   // Have to open the line to check specific device classes.
   lReturn = lineOpen(hLineApp, dwDeviceID, &hLine,
      dwApiVersion, 0, 0, LINECALLPRIVILEGE_NONE, 0, 0);

   if (lReturn)
   {
      printf("lineOpen error: %s\n", FormatLineError(lReturn));
      return;
   }

   // Make sure the "comm/datamodem" device class is supported
   // Note that we don't want any of the 'extra' information
   // normally returned in the VARSTRING structure.  All we care
   // about is if lineGetID succeeds.
   lReturn = lineGetID(hLine, 0, 0, LINECALLSELECT_LINE,
      &SmallVarString, "comm/datamodem");

   if (lReturn)
      bSupportsDataComm = FALSE;

   // Print the comm/datamodem results.
   if (bSupportsDataComm)
      printf("Y, ");
   else
      printf("N, ");

   // Make sure both "wave/in" and "wave/out" device classes are supported.
   lReturn = lineGetID(hLine, 0, 0, LINECALLSELECT_LINE,
      &SmallVarString, "wave/in");
   if (lReturn)
      bSupportsAutomatedVoice = FALSE;
   else
   {
      lReturn = lineGetID(hLine, 0, 0, LINECALLSELECT_LINE,
         &SmallVarString, "wave/out");
      if (lReturn)
         bSupportsAutomatedVoice = FALSE;
   }

   // Print the automatedvoice results.
   if (bSupportsAutomatedVoice)
      printf("Y, ");
   else
      printf("N, ");

   lReturn = lineGetLineDevStatus(hLine, &LineDevStatus);
   if (lReturn)
   {
      printf("lineGetLineDevStatus error: %s\n", FormatLineError(lReturn));
      return;
   }

   // Any calls in progress?
   if (LineDevStatus.dwNumActiveCalls ||
       LineDevStatus.dwNumOnHoldCalls ||
       LineDevStatus.dwNumOnHoldPendCalls)
      printf("Y, ");
   else
      printf("N, ");

   // Any apps waiting for calls?
   if (LineDevStatus.dwOpenMediaModes)
      printf("Y, ");
   else
      printf("N, ");

   // Track down the Service Provider that owns this line device.
   // Looking for: HIWORD(dwPermanentLineID) == dwPermanentProviderID
   dwCount = lpLineProviderList->dwNumProviders;
   while(dwCount--)
   {
      if (HIWORD(lpLineDevCaps->dwPermanentLineID) == 
          lpLineProviderEntry[dwCount].dwPermanentProviderID)
      {
         printf("%s - ", (char *)
            ((BYTE *) lpLineProviderList + 
               lpLineProviderEntry[dwCount].dwProviderFilenameOffset));
         dwCount = 1;
         break;
      }
   }
   if (dwCount != 1)
      printf("Unknown TSP - ");

   // Find the name of the line device
   if ((lpLineDevCaps -> dwLineNameSize) &&
       (lpLineDevCaps -> dwLineNameOffset) &&
       (lpLineDevCaps -> dwStringFormat == STRINGFORMAT_ASCII))
   {
      // This is the name of the device.
      lpszLineName = (char *)
         ((BYTE *) lpLineDevCaps + lpLineDevCaps -> dwLineNameOffset);

      if (lpszLineName[0] != '\0')
      {
         // If the device name is not null terminated, null
         // terminate it.  Yes, this looses the end character.
         // Its a bug in the service provider.
         lpszLineName[lpLineDevCaps->dwLineNameSize-1] = '\0';
      }
      else // Line name started with a NULL.
         lpszLineName = szLineNameEmpty;
   }
   else  // DevCaps doesn't have a valid line name.  Unnamed.
      lpszLineName = szLineUnnamed;

   printf("%s\n",lpszLineName);
   lineClose(hLine);
}


void CALLBACK lineCallbackFunc(
    DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, 
    DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
   // Not used for anything.
}


// Turn a TAPI Line error into a printable string.
char * FormatLineError (long lError)
{
   static LPSTR pszLineError[] = 
   {
      "LINEERR No Error",
      "LINEERR_ALLOCATED",
      "LINEERR_BADDEVICEID",
      "LINEERR_BEARERMODEUNAVAIL",
      "LINEERR Unused constant, ERROR!!",
      "LINEERR_CALLUNAVAIL",
      "LINEERR_COMPLETIONOVERRUN",
      "LINEERR_CONFERENCEFULL",
      "LINEERR_DIALBILLING",
      "LINEERR_DIALDIALTONE",
      "LINEERR_DIALPROMPT",
      "LINEERR_DIALQUIET",
      "LINEERR_INCOMPATIBLEAPIVERSION",
      "LINEERR_INCOMPATIBLEEXTVERSION",
      "LINEERR_INIFILECORRUPT",
      "LINEERR_INUSE",
      "LINEERR_INVALADDRESS",
      "LINEERR_INVALADDRESSID",
      "LINEERR_INVALADDRESSMODE",
      "LINEERR_INVALADDRESSSTATE",
      "LINEERR_INVALAPPHANDLE",
      "LINEERR_INVALAPPNAME",
      "LINEERR_INVALBEARERMODE",
      "LINEERR_INVALCALLCOMPLMODE",
      "LINEERR_INVALCALLHANDLE",
      "LINEERR_INVALCALLPARAMS",
      "LINEERR_INVALCALLPRIVILEGE",
      "LINEERR_INVALCALLSELECT",
      "LINEERR_INVALCALLSTATE",
      "LINEERR_INVALCALLSTATELIST",
      "LINEERR_INVALCARD",
      "LINEERR_INVALCOMPLETIONID",
      "LINEERR_INVALCONFCALLHANDLE",
      "LINEERR_INVALCONSULTCALLHANDLE",
      "LINEERR_INVALCOUNTRYCODE",
      "LINEERR_INVALDEVICECLASS",
      "LINEERR_INVALDEVICEHANDLE",
      "LINEERR_INVALDIALPARAMS",
      "LINEERR_INVALDIGITLIST",
      "LINEERR_INVALDIGITMODE",
      "LINEERR_INVALDIGITS",
      "LINEERR_INVALEXTVERSION",
      "LINEERR_INVALGROUPID",
      "LINEERR_INVALLINEHANDLE",
      "LINEERR_INVALLINESTATE",
      "LINEERR_INVALLOCATION",
      "LINEERR_INVALMEDIALIST",
      "LINEERR_INVALMEDIAMODE",
      "LINEERR_INVALMESSAGEID",
      "LINEERR Unused constant, ERROR!!",
      "LINEERR_INVALPARAM",
      "LINEERR_INVALPARKID",
      "LINEERR_INVALPARKMODE",
      "LINEERR_INVALPOINTER",
      "LINEERR_INVALPRIVSELECT",
      "LINEERR_INVALRATE",
      "LINEERR_INVALREQUESTMODE",
      "LINEERR_INVALTERMINALID",
      "LINEERR_INVALTERMINALMODE",
      "LINEERR_INVALTIMEOUT",
      "LINEERR_INVALTONE",
      "LINEERR_INVALTONELIST",
      "LINEERR_INVALTONEMODE",
      "LINEERR_INVALTRANSFERMODE",
      "LINEERR_LINEMAPPERFAILED",
      "LINEERR_NOCONFERENCE",
      "LINEERR_NODEVICE",
      "LINEERR_NODRIVER",
      "LINEERR_NOMEM",
      "LINEERR_NOREQUEST",
      "LINEERR_NOTOWNER",
      "LINEERR_NOTREGISTERED",
      "LINEERR_OPERATIONFAILED",
      "LINEERR_OPERATIONUNAVAIL",
      "LINEERR_RATEUNAVAIL",
      "LINEERR_RESOURCEUNAVAIL",
      "LINEERR_REQUESTOVERRUN",
      "LINEERR_STRUCTURETOOSMALL",
      "LINEERR_TARGETNOTFOUND",
      "LINEERR_TARGETSELF",
      "LINEERR_UNINITIALIZED",
      "LINEERR_USERUSERINFOTOOBIG",
      "LINEERR_REINIT",
      "LINEERR_ADDRESSBLOCKED",
      "LINEERR_BILLINGREJECTED",
      "LINEERR_INVALFEATURE",
      "LINEERR_NOMULTIPLEINSTANCE"
   };

   static char szUnknown[256];
   DWORD dwError;

   // Strip off the high bit to make the error code positive.
   dwError = (DWORD)lError & 0x7FFFFFFF;

   if ((lError > 0) || (dwError > sizeof(pszLineError)))
   {
      wsprintf(szUnknown, "Unknown TAPI line error code: 0x%lx", lError);
      return szUnknown;
   }

   return pszLineError[dwError];
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -