C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: HIDデバイスのオープンで失敗する


(過去ログ 93 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■55818 / inTopicNo.1)  HIDデバイスのオープンで失敗する
  
□投稿者/ 焦げ太 (5回)-(2010/12/15(Wed) 09:43:29)

分類:[C/C++] 

お世話になります。

USB(HID)の市販バーコードリーダーからデータを取得するDLLを
作ろうとしています。

SetupDiGetDeviceInterfaceDetailにて取得したドライバパスを
CreateFileでオープンを試みておりますが、失敗が返ります。

この掲示板で同じような質問がありました。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=35352&KLOG=61

回答として、
 ・自作でない HID の場合、Windows 自体が制御をつかんでいるので
  フツーにやったのでは開けない
 ・DuplicateHandleで複製して利用できるはず
とありました。

試しに、SetupDiGetClassDevsにて取得したHDEVINFOをDuplicateHandle
してみたのですが、失敗が返ります。ネット検索でDuplicateHandleの
使い方は調べたのですが理解できておりません(汗

使用している言語はVC++2008で、ソースは以下になります。

GUID hidGuid;
HDEVINFO devInfo, copyDevInfo;

//GUIDの取得
HidD_GetHidGuid(&hidGuid);

//HIDクラスのデバイスリストへのハンドルを取得
devInfo = SetupDiGetClassDevs(&hidGuid, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (devInfo == NULL) return FALSE;

if (DuplicateHandle(
  GetCurrentProcess(),	// 複製元プロセスのハンドル
  devInfo,		// 複製対象のハンドル
  GetCurrentProcess(),	// 複製先プロセスのハンドル
  &copyDevInfo,		// 複製先ハンドル
  0,			// 複製ハンドルで必要なアクセス権
  FALSE,			// ハンドル継承フラグ
  DUPLICATE_SAME_ACCESS    // オプションの動作
) == FALSE) return;     //<--- FALSEが返ってきます

質問したいことは、、、

(1)DuplicateHandleで複製することにより「Windows 自体が制御を
 つかんでいるHIDデバイス」を開くことは可能でしょうか?

(2) (1)が可能な場合、DuplicateHandleの使用方法の間違いを
   ご指摘いただきたいです。そもそも複製するハンドルは
   HDEVINFO であっておりますでしょうか?

ご教授のほど宜しくお願いします。

引用返信 編集キー/
■55819 / inTopicNo.2)  Re[1]: HIDデバイスのオープンで失敗する
□投稿者/ aetos (351回)-(2010/12/15(Wed) 10:46:36)
No55818 (焦げ太 さん) に返信
> (1)DuplicateHandleで複製することにより「Windows 自体が制御を
>  つかんでいるHIDデバイス」を開くことは可能でしょうか?
>
> (2) (1)が可能な場合、DuplicateHandleの使用方法の間違いを
> ご指摘いただきたいです。そもそも複製するハンドルは
> HDEVINFO であっておりますでしょうか?

ダメでしょう。
DuplicateHandle で複製できるハンドルは以下のページに列挙されているものだけです。
http://msdn.microsoft.com/ja-jp/library/ms724251.aspx
引用返信 編集キー/
■55823 / inTopicNo.3)  Re[2]: HIDデバイスのオープンで失敗する
□投稿者/ 焦げ太 (6回)-(2010/12/15(Wed) 11:52:17)
aetosさん、ご返信ありがとうございます。

> ダメでしょう。
> DuplicateHandle で複製できるハンドルは以下のページに列挙されているものだけです。
> http://msdn.microsoft.com/ja-jp/library/ms724251.aspx

確認しました。
情報ありがとうございます。

DuplicateHandleがNGなことはわかりましたが、、、
別の方法って何かあるのでしょうか??
ご存知の方おりましたら教えてください。
よろしくお願いします。

引用返信 編集キー/
■55827 / inTopicNo.4)  Re[1]: HIDデバイスのオープンで失敗する
□投稿者/ shu (292回)-(2010/12/15(Wed) 12:30:15)
No55818 (焦げ太 さん) に返信

全然関係ないかもしれませんが、
バーコードリーダってつなげればそのままキーボードのように
使えるのではないですか?

そういう使い方でなかったらごめんなさい。
引用返信 編集キー/
■55828 / inTopicNo.5)  Re[2]: HIDデバイスのオープンで失敗する
□投稿者/ 焦げ太 (7回)-(2010/12/15(Wed) 12:43:11)
shu さん、返信ありがとうございます。

No55827 (shu さん) に返信
> ■No55818 (焦げ太 さん) に返信
>
> 全然関係ないかもしれませんが、
> バーコードリーダってつなげればそのままキーボードのように
> 使えるのではないですか?
>
> そういう使い方でなかったらごめんなさい。

具体的な事情は説明できないのですが、バーコードリーダーから
取得したデータを加工してからキーボードデータとして投げたい
のです。

あと記述いたしませんでしたが、正確にはバーコードリーダーでは
なくて二次元コードリーダーにあたります。
QRコードが読めるものです。よって2バイトデータも送られてきます。

引用返信 編集キー/
■55836 / inTopicNo.6)  Re[3]: HIDデバイスのオープンで失敗する
□投稿者/ shu (295回)-(2010/12/15(Wed) 14:17:45)
No55828 (焦げ太 さん) に返信

> 具体的な事情は説明できないのですが、バーコードリーダーから
> 取得したデータを加工してからキーボードデータとして投げたい
> のです。
>
> あと記述いたしませんでしたが、正確にはバーコードリーダーでは
> なくて二次元コードリーダーにあたります。
> QRコードが読めるものです。よって2バイトデータも送られてきます。
なるほど、そのまま飛んでくるデータを渡すわけではないのですね。

http://noritan-micon.blog.so-net.ne.jp/2008-03-11
こんなサイトありましたが使えますか?
引用返信 編集キー/
■55840 / inTopicNo.7)  Re[4]: HIDデバイスのオープンで失敗する
□投稿者/ 焦げ太 (8回)-(2010/12/15(Wed) 15:10:23)
shu さん、ご返信ありがとうございます。
ご提示いただいたサイトは既に拝見しておりました。
「STEP5: お目当てのデバイスを探せ」にあるCreateFileで
失敗する状態です。

以下、ソースですが、DuplicateHandleを試す前のものです。
HIDはマウス、キーボード、バーコードリーダーと3つが
PCとつながっており、3つとも2度目の
SetupDiGetDeviceInterfaceDetailまでは成功しますが
CreateFileでFALSEになります。

何か情報がありましたら、宜しくお願いします。

------------------------------------------------------------------
DllExport BOOL WINAPI ExportHIDList(char *file_path)
{
    GUID hidGuid;
    HDEVINFO devInfo;
    SP_DEVICE_INTERFACE_DATA spid;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = NULL;
    HANDLE hDevHandle;
    HIDD_ATTRIBUTES Attributes;
    char msg[512];
    char devname[512];

    //GUIDの取得
    HidD_GetHidGuid(&hidGuid);

    //HIDクラスのデバイスリストへのハンドルを取得
    devInfo = SetupDiGetClassDevs(&hidGuid, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (devInfo == NULL) return FALSE;

    //HIDクラスのデバイスの列挙
    DWORD dwIndex = 0;
    while (TRUE) 
    {
        memset(&spid, 0, sizeof(spid));
        spid.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        if (SetupDiEnumDeviceInterfaces(devInfo, NULL, &hidGuid, dwIndex, &spid) == TRUE)
        {
            //デバイス詳細用の長さを取得
            DWORD dwRequiredLength = 0;
            SetupDiGetDeviceInterfaceDetail(devInfo, &spid, NULL, 0, &dwRequiredLength, NULL);

            //デバイス詳細用メモリ確保
            pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(dwRequiredLength);
            pdidd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

            //デバイスの詳細を取得
            if (SetupDiGetDeviceInterfaceDetail(devInfo, 
                                                &spid, 
                                                pdidd, 
                                                dwRequiredLength, 
                                                &dwRequiredLength, 
                                                NULL) == TRUE) 
            {
                //ロケール指定
                setlocale(LC_ALL, "japanese");
                //変換
                size_t wLen = 0;
                errno_t err = wcstombs_s(&wLen, devname, 512, pdidd->DevicePath, _TRUNCATE);

                //HIDにアクセスするためファイルを作成しハンドルを取得
                hDevHandle = CreateFile(pdidd->DevicePath, 
                                        GENERIC_READ, 
                                        0, //FILE_SHARE_READ, 
                                        NULL,
                                        OPEN_EXISTING, 
                                        0,
                                        NULL);
                if (hDevHandle == INVALID_HANDLE_VALUE)
                {
                    sprintf_s(msg, 512, "列挙 %d  INVALID HANDLE!\n[%s]\n",
                                  dwIndex+1,
                                  devname); 
                    ExportToFile(file_path, msg);
                }
                else 
                {
                    //デバイスのアトリビュートからベンダーID、プロダクトID、バージョンNoを取得
                    Attributes.Size = sizeof(Attributes);
                    if (HidD_GetAttributes(hDevHandle, &Attributes)) 
                    {
                        sprintf_s(msg, 512, "列挙 %d\nVID = %d\nPID = %d\nVsn = %d\n",
                                      dwIndex+1,
                                      Attributes.VendorID,
                                      Attributes.ProductID,
                                      Attributes.VersionNumber );
                        ExportToFile(file_path, msg);
                    }
                    CloseHandle(hDevHandle);
                }
            }

            free(pdidd);
            dwIndex++;
        }
        else 
        {
            if( GetLastError() == ERROR_NO_MORE_ITEMS )
            {
                ExportToFile(file_path, "------------ END -----------\n");
                break;
            }
        }
    }

    return TRUE;
}

引用返信 編集キー/
■55844 / inTopicNo.8)  Re[5]: HIDデバイスのオープンで失敗する
□投稿者/ aetos (352回)-(2010/12/15(Wed) 17:04:10)
No55840 (焦げ太 さん) に返信
> shu さん、ご返信ありがとうございます。
> ご提示いただいたサイトは既に拝見しておりました。
> 「STEP5: お目当てのデバイスを探せ」にあるCreateFileで
> 失敗する状態です。

GetLastError の戻り値はどうなりますか?
引用返信 編集キー/
■55887 / inTopicNo.9)  Re[6]: HIDデバイスのオープンで失敗する
□投稿者/ 焦げ太 (9回)-(2010/12/17(Fri) 12:09:36)
aetos さん、ご返信いただきながらご連絡が遅れて
申し訳ございません。
出張にてチェックできませんでした。

No55844 (aetos さん) に返信
> ■No55840 (焦げ太 さん) に返信
>>shu さん、ご返信ありがとうございます。
>>ご提示いただいたサイトは既に拝見しておりました。
>>「STEP5: お目当てのデバイスを探せ」にあるCreateFileで
>>失敗する状態です。
>
> GetLastError の戻り値はどうなりますか?

5が返りました。
FormatMessage()してみたらアクセス拒否でした。

引用返信 編集キー/
■55888 / inTopicNo.10)  Re[7]: HIDデバイスのオープンで失敗する
□投稿者/ 焦げ太 (10回)-(2010/12/17(Fri) 12:25:14)
関係ないかもしれませんが、環境です。

WindowsXP SP3
VS2008 SP1 VC++

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -