9

自分のコンピューター (win7 64 ビット) に接続されている PC/SC リーダーに IOCTL コマンドを送信したいと考えています。IOCTL コマンドを送信するには、デバイスに HANDLE が必要ですが、作成できません。

デバイスはデバイス マネージャーで「OMNIKEY 1021」としてリストされ、物理デバイス オブジェクト名は「\Device\USBPDO-15」です。Using the "WinObj" tool, I can detect 2 symlinks: USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530} USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

私の問題: CreateFile 関数を使用して、このデバイスへの有効なハンドルを作成できません。

MSDN/Google で、CreateFile 関数の lpFileName パラメータとして使用できるフォーマットをいくつか見つけましたが、どれも機能していないようです。

\\?\Device\USBPDO-15
\\.\Device\USBPDO-15
\\GLOBAL??\Device\USBPDO-15
\GLOBAL??\Device\USBPDO-15
\\.\USBPDO-15
\\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

コードサンプル:

#include <iostream>
#include <Windows.h>

int main (int argc, char* argv[])
{
    HANDLE handle = CreateFile (
        L"\\\\.\\Device\\USBPDO-15",
        0,
        FILE_SHARE_READ, //FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0, //FILE_FLAG_OVERLAPPED,
        NULL
    );

    if (handle == INVALID_HANDLE_VALUE)
        std::cout << "INVALID HANDLE" << std::endl;
    else
        std::cout << "HANDLE: " << std::hex << handle << std::endl;
}

ノート:

  • 返されるハンドルは常に無効です
  • 常に管理者として実行されるため、権限は問題になりません

編集:

解決:

  • PC/SC サービスはデバイスの排他的な所有権を取得するため、'CreateFile' を呼び出そうとすると常に失敗します。
  • 解決策はカーネル スペース ドライバーです。これにより、IRP をドライバーに渡すことができます。(デバイスとの間で送受信されるデータを変更する KMDF フィルター ドライバーを実装することができました)
4

2 に答える 2

9

私のやり方で試してみてください。Setup API を使用して、システム内のすべての USB アクティブ デバイスを列挙し、パスを取得しています。そうすれば、それがパスなのか他の引数なのかを知ることができますCreateFile

誰かが興味を持っている場合は、少し後でコメントを追加します。

HDEVINFO hDevInfo = SetupDiGetClassDevs( &_DEVINTERFACE_USB_DEVICE, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    if(hDevInfo == INVALID_HANDLE_VALUE)
    {
        return ERR_FAIL;
    }

    std::vector<SP_INTERFACE_DEVICE_DATA> interfaces;

    for (DWORD i = 0; true; ++i)
    {
        SP_DEVINFO_DATA devInfo;
        devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
        BOOL succ = SetupDiEnumDeviceInfo(hDevInfo, i, &devInfo);
        if (GetLastError() == ERROR_NO_MORE_ITEMS)
            break;
        if (!succ) continue;

        SP_INTERFACE_DEVICE_DATA ifInfo;
        ifInfo.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
        if (TRUE != SetupDiEnumDeviceInterfaces(hDevInfo, &devInfo,  &(_DEVINTERFACE_USB_DEVICE), 0, &ifInfo))
        {
            if (GetLastError() != ERROR_NO_MORE_ITEMS)
                break;
        }
        interfaces.push_back(ifInfo);
    }

    std::vector<SP_INTERFACE_DEVICE_DETAIL_DATA*> devicePaths;
    for (size_t i = 0; i < interfaces.size(); ++i)
    {
        DWORD requiredSize = 0;
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), NULL, NULL, &requiredSize, NULL);
        SP_INTERFACE_DEVICE_DETAIL_DATA* data = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc(requiredSize);
        assert (data);
        data->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

        if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), data, requiredSize, NULL, NULL))
        {
            continue;
        }
        devicePaths.push_back(data);
    }
于 2011-11-28T14:40:42.530 に答える