1


1

SetupDiGetDeviceInterfaceDetail()を使用して、コンピューターにインストールされているシリアルポートに関する情報を見つけるアプリケーションを保守しています。 これをテストしているうちに、Lucent WinModemなど、その列挙に表示されないデバイスがいくつかあることに気付きました。 シリアルポートインターフェイスを実装している私の会社で製造されている一連のデバイスにも同様の問題があります。 私の仮定は、デバイスのINFファイルに欠けているものがあるということです。 どんな種類の条件がこの種の省略をもたらす可能性があるか誰かが知っていますか?

編集:これは私がシリアルポートを列挙するために使っているコードのサンプルです。 さまざまなフラグの組み合わせを試しましたが、動作に大きな違いは見られませんでした。

DEFINE_GUID(GUID_CLASS_COMPORT、0x4d36e978、0xe325、0x11ce、0xbf、0xc1、\ 0x08、0x00、0x2b、0xe1、0x03、0x18)。

GUID * serial_port_guid = const_cast(

device_info = SetupDiGetClassDevs(serial_port_guid、0、0、DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(device_info!= INVALID_HANDLE_VALUE){uint4 const detail_data_size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)256; detail_data = reinterpret_cast(new char [detail_data_size]); SP_DEVICE_INTERFACE_DATA ifc_data。 bool more_interfaces = true; int rcd; memset(

rcd = SetupDiGetDeviceRegistryProperty(device_info、

4 Answer


4


これはもっと問題についての質問です。 この関数を呼び出すときに最初に渡す引数は、おそらくhttp://msdn.microsoft.com/ja-jp/library/ms792959.aspx[SetupDiGetClassDevs]関数から取得したDeviceInfoSetである必要があります。 SetupDiGetClassDevs関数を呼び出したときに、フラグに対して何を指定しましたか(最後の引数)。

_ _ * DIGCF_ALLCLASSES *すべてのデバイスセットアップクラスまたはすべてのデバイスインターフェイスクラスのインストール済みデバイスのリストを返します。

  • DIGCF_DEVICEINTERFACE *指定された装置インターフェース・クラスの装置インターフェースをサポートする装置を戻します。 EnumeratorパラメータがデバイスインスタンスIDを指定している場合は、このフラグをFlagsパラメータに設定する必要があります。

  • DIGCF_DEFAULT *指定された装置インターフェース・クラスについて、システムのデフォルト装置インターフェース(設定されている場合)に関連した装置だけを戻します。

  • DIGCF_PRESENT *現在システムに存在するデバイスだけを返します。

  • DIGCF_PROFILE *現在のハードウェアプロファイルの一部であるデバイスだけを返します。 _ _

選択に応じて、デバイスのリストが変わります。 たとえば、Presentフラグはアクティブに接続されているデバイスのみを表示します。

'' '' '

更新:サンプルコードをありがとう。

私の質問は、モデムのフレンドリ名を知りたいのであれば、同じ呼び出しを使用せず、COMポートの代わりにModem Guidを指定するのですか。 モデムGUIDが4D36E96D-E325-11CE-BFC1-08002BE10318である

レジストリには、COMポートを指定する 'AttachedTo’という値があります。 私はどのプロパティがthatsに結び付けられているかを調べなければならないでしょう。 レジストリキーは

HKLM \ SYSTEM \ CurrentControlSet \ Control \ Class \ {4D36E96D-E325-11CE-BFC1-08002BE10318} \

'' '' '

別のアップデート:

サンプルコードをよく見てください。 これに基づいて、http://msdn.microsoft.com/en-us/library/ms793116.aspx[SP_DEVICE_INTERFACE_DETAIL_DATA]構造体を返す必要があるデバイスインターフェイスクラスを取得しようとしている場合。 それはデバイスのフレンドリ名を取得する方法を提供しません。 代わりに、デバイスインスタンスが欲しいと思うでしょう。

私が読んだものから、それに書き込むために使用することができるデバイスパスを取得する方法としてデバイスインターフェイスが使用されています。

あなたのコードをテストするために私がしたことの1つは、それをもう一度ディスク装置インターフェースで試すことでした。 私のシステムで動作させるためにいくつか変更を加えましたが、それでもまだうまくいきません。 1つの問題(おそらくそれ以上)は、SetupDiGetDeviceInterfaceDetail呼び出しの間にDevicePath変数のサイズを変更する必要があるということです。

void Test()
{

GUID *serial_port_guid = const_cast(&GUID_DEVINTERFACE_DISK);
HDEVINFO device_info = INVALID_HANDLE_VALUE;
SP_DEVICE_INTERFACE_DETAIL_DATA detail_data;

device_info = SetupDiGetClassDevs(
   serial_port_guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if(device_info != INVALID_HANDLE_VALUE)
{
   //uint4 const detail_data_size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);// + 256;
   //detail_data = reinterpret_cast(new char[detail_data_size]);
   SP_DEVICE_INTERFACE_DATA ifc_data;
   bool more_interfaces = true;
   int rcd;
   memset(&ifc_data, 0, sizeof(ifc_data));
   //memset(detail_data, 0, detail_data_size);
   ifc_data.cbSize = sizeof(ifc_data);
   detail_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
   for(uint4 index = 0; more_interfaces; ++index)
   {
      rcd = SetupDiEnumDeviceInterfaces(device_info, 0, serial_port_guid, index, &ifc_data);
      if(rcd)
      {
         // we need to get the details of this device
         SP_DEVINFO_DATA device_data;
         device_data.cbSize = sizeof(SP_DEVINFO_DATA);
         DWORD intReqSize;
         rcd = SetupDiGetDeviceInterfaceDetail(device_info, &ifc_data, 0, 0, &intReqSize, &device_data);

         rcd = SetupDiGetDeviceInterfaceDetail(device_info, &ifc_data, &detail_data,intReqSize,&intReqSize,&device_data);
         if(rcd)
         {
            //StrAsc device_path(detail_data->DevicePath);
            byte friendly_name[256];

            rcd = SetupDiGetDeviceRegistryProperty(
               device_info, &device_data, SPDRP_FRIENDLYNAME, 0, friendly_name, sizeof(friendly_name), reinterpret_cast(sizeof(friendly_name)));
            if(rcd)
            {
              cout<(friendly_name);
            }
            else
            {   int num = GetLastError();
            }
         }
         else
         {
                int num = GetLastError();
            }
      }
      else
            more_interfaces = false;
   }
}
SetupDiDestroyDeviceInfoList(device_info);
}

また、INFでは、ドライバを正しいインターフェイスに関連付けるためにhttp://msdn.microsoft.com/en-us/library/ms794355.aspx[AddInterface]ディレクティブを追加する必要があります。


1


に記載されているように、以下の修正プログラムが問題を解決するかどうかわかりません。

もう1つ興味深い点は、GUID_CLASS_COMPORTはWin2000以降では使用されていないことです。

もう一つのサイト私は9つの異なる列挙方法があると思います。 頑張ってください。


0


あなたはあなたのデバイスが存在しアクセス可能だと言っていますが、あなたはあなたのデバイスに直接アクセスしているのですか、それとも名前と番号COMnでポートにアクセスしていますか?

オーディオドライバに接続されているWinModemがあります。 私はシリアルポートを持っていません。シミュレートされたものさえ持っていません。


-1


私はこれをパントし、SetupDi()関数への依存をやめることにしました。 代わりに、シリアルポートGUIDをサポートするドライバを見つけるために、HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Enumにサブキーを横断するコードを書きました。 私はこれがデバイスマネージャがすることであると感じています。 誰かが興味を持った場合、私のコードの断片は以下のようになります。

typedef std :: string StrAsc; typedef std :: pair port_name_type; typedef std :: list friendly_names_type; void SerialPortBase :: list_ports_friendly(friendly_names_type) これにより、少なくとも、他の方法で取得したのと同じ名前リストが確実に取得されます。 port_names_type simple_list; list_ports(simple_list); port_names.clear(); (port_names_type :: iterator pi = simple_list.begin(); pi!= simple_list.end(); pi)port_names.push_back(friendly_name_type(* pi、* pi));の場合。

// Enumレジストリキーのサブキーを列挙する必要があります。 これを行うには、//多くのレベルのレジストリキー構造を考慮する必要があるので、//キーハンドルのリストをスタックとして使用します。 HKEY enum_key; char const enum_key_name [] = "SYSTEM \\ CurrentControlSet \\ Enum"; StrAsc const com_port_guid( "{4d36e978-e325-11ce-bfc1-08002be10318}"); char const class_guid_name [] = "ClassGUID"; char const friendly_name_name [] = "FriendlyName"; char const device_parameters_name [] = "デバイスパラメータ"; char const port_name_name [] = "PortName"; long rcd = :: RegOpenKeyEx(HKEY_LOCAL_MACHINE、enum_key_name、0、KEY_READ、

if(!port_names.empty() フレンドリ名//を取得し、 'Device Parameters'サブキーから 'PortName'を取得する必要があります。 //これらができたら、元のリストのフレンドリ名を更新できます。value_buff_len = sizeof(value_buff); rcd = :: RegQueryValueEx(current、friendly_name_name、0、0、reinterpret_cast(value_buff)、
               ++index;
:: RegCloseKey(現在の); // list_ports_friendly