用CreateFile函数得到串口句柄,然后用 GetCommProperties 函数得到modem的配置情况。
一台机器中串口不会太多,一般只有两个,循环查一下就行了。HANDLE hCom = CreateFile( "COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,    // comm devices must be opened w/exclusive-access 
    NULL, // no security attributes 
    OPEN_EXISTING, // comm devices must use OPEN_EXISTING 
    0,    // not overlapped I/O 
    NULL  // hTemplate must be NULL for comm devices 
    );if (hCom == INVALID_HANDLE_VALUE) 
{
    dwError = GetLastError();    // handle error 
}BOOL GetCommProperties(
  HANDLE hFile,           // handle to comm device
  LPCOMMPROP lpCommProp   // pointer to comm properties structure
);
 

解决方案 »

  1.   

    下面是http://www.experts-exchange.com  DanRollins 专家的回答:
    It's not too easy to do programmatically -- see the TAPI documentation.  
    All of the system functions hide the actual port for each modem. Maybe this will help: ShellExecute( "open", "RunDLL32","shell32.dll,Control_RunDLL MODEM.CPL" ); This brings up the Control Panel which will show you which com port is 
    attached to each modem. Is that any help? -- Dan 下面是DanRollins 专家的简介:Name: DanRollins   First Login:  4/18/00  Expert Points:  41679 
     
    Profile:  
    Programmer since the dawn of time. 
    Author of a published book (Macmillan) on Intel Assembly language programming.  Question History:  
    Questions Asked: 12         Questions Answered: 111              Last 6 Grade(s) Given:  
    A A A A D A  
    Last 10 Grade(s) Received:  
    B A A A A A A A A A  
    Question Grading Record:  
    6 / 6  有一定难度 "All of the system functions hide the actual port for each modem. "希望各位中国专家能解决此问题,我一定为此问题加分
      

  2.   

    谢谢各位专家的回答:
    我的主机上可能安装1-255各COM口(用MOXA nPorter),每个COM口挂接一个MODEM,用TAPI编程是我可以枚举出所有MODEN线路的lineDeviceID,但在系统组态时我只1-255各COM口,运行时需要将COM口和MODEN线路的lineDeviceID相匹配,所以我需从MODEN线路的lineDeviceID找出它使用的COM口。
      

  3.   

    根据MSDN中的介绍,使用lineGetID函数可以得到指定modem连接的串口号。原文如下:
    The comm/datamodem/portname device class consists of the device names to which modems are attached. When this device name is specified in a call to the lineGetID function, the function fills the VARSTRING structure with a null-terminated ANSI (not Unicode) string specifying the name of the port to which the specified modem is attached, such as "COM1\0". 
      

  4.   

    From: DanRollins 
     Date: Thursday, November 09 2000 - 12:50PM PST  
    The TAPI documentation is peppered with the words "opaque structure"  That is, many calls return a structure full of data that is undocumented and that we are not supposed to look at or use. Believe me, I tried hard to solve this in an important project, but was never able to.  TAPI is *meant* to hide these details. By trial and error, I found that the registry contains the com port for *some* modems (partial code follows): HKEY hkModem, hkMdmNNNN; lRet= RegOpenKey( HKEY_LOCAL_MACHINE, 
      "System\\CurrentControlSet\\Services\\Class\\Modem", 
      &hkModem); for ( j=0; j< 10; j++ ) { 
      lCbKeyName= sizeof(szKeyName); 
      lRet=RegEnumKeyEx( hkModem, j, 
        szKeyName, &lCbKeyName, 
        0,    // reserved 
        0, 0, // class buffer and its length not needed 
        &rFT 
      ); 
      if (lRet != ERROR_SUCCESS) { // == ERROR_NO_MORE_ITEMS 
        break; 
      }   lRet= RegOpenKey( hkModem, szKeyName, &hkMdmNNNN ); 
      if (lRet != ERROR_SUCCESS) { 
        break; 
      } 
      if ( GetRegValue(hkMdmNNNN, "AttachedTo", szBuf, sizeof(szBuf)) ) { 
        if ( _fmemicmp (szBuf,"COM", 3) == 0 ) { 
          szBuf[3]--;                                //eg, COM2 goes in as Port=1 
        } 
      else { 
        return( FALSE );     // not a comm port 
      } 
    } ---------- 
    the above code specifically does *not* work on NT.  It also does not work on some (perhaps many) modems because the modem driver hiide the port internally (never revealing it in the registry). -=-=-=-=-=-=-=- 
    Here's an idea out of desperation: Bring up the modem configuration dialog (as described previously) and "screen scrape" the COM port. 
    -=-=-=-=-=-=-=- 
    Here's another Idea: Open each com port and try sending AT<cr>  If it responds with "OK" then it is a modem. -=-=-=-=-= 
    News flash: 
    I just found a reasonable solution (if you are expecting TAPI 2.0 on the target machines.  See: http://members.tripod.com/tapifaq/tapifaq6.html It boils down to calling lineGetID with the name "comm/datamodem/portname" It should return a name like "COM1" -- Dan  
      

  5.   

    From: DanRollins 
     Date: Friday, November 10 2000 - 08:58AM PST  
    Here is the relevant text from that page (BTW i just clicked the link in your comment, so it is correct): 2. How can I get the name of the COM port my modem is connected to? TAPI applications really should not need to know about COM ports, especially since there is a great deal of TAPI hardware available that doesn't make use of COM ports at all. If all you intend to do is display information in your application then you should rely on device information in the LINEADDRESSCAPS and LINEDEVCAPS structures as well as functions such as lineConfigDialog and not try to make use of COM port information yourself. There can be times when you may have a valid reason to get the name of the COM port a modem is connected to. Unfortunately, the TAPI specification for versions 1.4 and earlier did not include any means of determining this information. As of TAPI 2.0, the device ID "comm/datamodem/portname" is listed as one of the standard recognized device ID's. So if you are using TAPI 2.0 or later you can call lineGetID with this device ID, and if the service provider you are using makes use of a COM port it should return you the string name of the port (i.e. "COM1"). Although the "comm/datamodem/portname" device ID was introduced with TAPI 2.0, it is possible for some TAPI 1.x TSP's to support it. Device ID strings are simply passed through TAPI to the TSP being used, and if the TSP recognizes the string it will return the appropriate information. So companies that have developed TAPI 1.x TSP's after the TAPI 2.0 specifications were released, it's possible they may support this device ID as well. Keep in mind, however, that there is no requirement that a TSP support this, or any other device ID. So when you call lineGetID with this device ID you may get a LINEERR_OPERATIONUNAVAIL error which would indicate the TSP doesn't recognize the device ID. IF you know that your application is using the Unimodem or Unimodem/V service provider then there is another way you can obtain the name of the COM port, no matter what version of TAPI you are using. This method is not supported by Microsoft, and future versions of Unimodem may behave differently, so use this method at your own risk. The Unimodem and Unimodem/V service providers store a partial registry key in the dwDeviceSpecific fields of the LINEDEVCAPS structure. If you look in the registry under this key you can locate the name of the COM port and other information. For example, if you examine the LINEDEVCAPS for a modem you would find a string similar to this: SYSTEM\CurrentControlSet\Control\Class\{4D36E96D-E325-11CE-BFC1-08002BE10318}\0000 If you look in the registry under this key under the HKEY_LOCAL_MACHINE key then you will find a string value named "AttachedTo". The value of this string is the identifier of the COM port that the modem is connected to. -- Dan  
      

  6.   

    COMMTIMEOUTS commtimeouts;
       DCB dcb;
       DWORD dwSize;
       COMMPROP *commprop;
       DWORD fdwEvtMask;
       DWORD dwError;   dwSize = sizeof(COMMPROP);
       commprop = (COMMPROP *)malloc(dwSize);
       memset(commprop, 0, dwSize);   GetCommState(hComm, &dcb);
       if(!GetCommProperties(hComm, commprop))
       {
         if(GetLastError()==122)
         {
            free(commprop);
            dwSize = sizeof(COMMPROP) + sizeof(MODEMDEVCAPS);
            commprop = (COMMPROP *)malloc(dwSize);
            memset(commprop, 0, dwSize);        commprop->wPacketLength = dwSize;
            commprop->dwProvSubType = PST_MODEM;
            commprop->dwProvSpec1 = COMMPROP_INITIALIZED;
            if(!GetCommProperties(hComm, commprop))
            {
              dwError = GetLastError();
            }
         }
       }   free(commprop); 
      

  7.   

    dingsg:
       谢谢你的回答,从hComm可知COM口,但我从MODEMDEVCAPS和COMMPROP里没找到modem线路的dwDeviceID(从lineInitializeEx()而来的),谢谢你能祥解。