1

C/C++ を使用して USB ポートを有効または無効にする方法を教えてください。

Windowsレジストリを使用してこれを行う方法をすでに検索しましたが、いくつかの問題があります。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\USBSTOR

開始値の値を 3 に変更します----ブロック解除 4 ----ブロック

Windows 7 では正しい動作が表示されません。たとえば、開始値の値を 4 に変更すると、USB ポートが無効になりますが、再度有効にするには、システムを再起動する必要があり、すべてのポートを無効にした後にもう 1 つが無効になります。すでに接続されているデバイスを使用できます。

それを行う他の方法はありますか?

4

2 に答える 2

1

devcon ユーティリティを使用して、これに対するもう 1 つの解決策を見つけました。USB デバイスを有効および無効にするためのさまざまなコマンドを提供します。

http://msdn.microsoft.com/en-us/library/windows/hardware/ff544746(v=vs.85).aspx#ddk_example_31_disable_devices_by_device_instance_id_tools

ただし、コマンドを実行するには管理者権限が必要であり、そのためのソース コードはありません。

USB デバイス用のプログラムを作成するための libusb-win32 ライブラリについて聞いたことがあります。

だから誰もそれについて考えている..

どんな助けでも大歓迎です..

皆さん、ありがとうございました..

于 2013-10-11T05:17:58.537 に答える
1

これは、デバイス検出に関する質問に対するコメントに本当に答えています。

コンソール アプリケーションで隠しウィンドウを作成します。

DevNotifierこの例では、HWND hidden_wnd_;メンバー変数を持つ というクラスがあることを前提としています。

static TCHAR const        s_window_class[] = _T("Device notification window");
static TCHAR const* const s_window_title   = s_window_class;

LRESULT CALLBACK 
DevNotifierWndProc(
    HWND    hWnd, 
    UINT    message, 
    WPARAM  wParam, 
    LPARAM  lParam
) {
    DevNotifier* dn = (DevNotifier*) ::GetWindowLongPtr(hWnd, GWLP_USERDATA);
    switch (message)
    {
    case WM_DEVICECHANGE:
        dn->onWM_DEVICECHANGE(
            wParam,
            lParam
        );
    break;
    default:
        return ::DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

void
DevNotifier::createHiddenWindow()
{
        HINSTANCE hinstance = ::GetModuleHandle(NULL);

        if ((hinstance == 0) || (hinstance == INVALID_HANDLE_VALUE))
        {
            throw Exception("Failed to get application instance handle.");
        }

        // register window class

        WNDCLASSEX wcex;

        ::memset(&wcex, 0, sizeof(wcex));

        wcex.cbSize = sizeof(WNDCLASSEX);

        wcex.style          = 0;
        wcex.lpfnWndProc    = &DevNotifierWndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hinstance;
        wcex.hIcon          = 0;
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = 0;
        wcex.lpszMenuName   = 0;
        wcex.lpszClassName  = s_window_class;
        wcex.hIconSm        = 0;

        (void) ::RegisterClassEx(&wcex);

        // Create the window

        hidden_wnd_ = ::CreateWindow(
            s_window_class, 
            s_window_title,
            WS_POPUP,
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
            CW_USEDEFAULT, 
            NULL, 
            NULL, 
            hinstance, 
            NULL
        );

        if (!hidden_wnd_) {
            throw Exception("Failed to create device notification window");
        }
    #ifdef _WIN64
        ::SetWindowLongPtr(static_cast<HWND>(hidden_wnd_), GWLP_USERDATA, (LONG_PTR)this);
    #else
        ::SetWindowLongPtr(static_cast<HWND>(hidden_wnd_), GWLP_USERDATA, (LONG)this);
    #endif
        ::ShowWindow(static_cast<HWND>(hidden_wnd_), SW_HIDE);
}

hidden_​​wnd_ で通知を登録できます。
例えば

    DEV_BROADCAST_DEVICEINTERFACE filter;
    ZeroMemory(&filter, sizeof(filter));
    filter.dbcc_size = sizeof(filter);
    filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    filter.dbcc_classguid = /* SOME INTERFACE GUID */;
    HDEVNOTIFY hdn = ::RegisterDeviceNotification(
        hidden_wnd_, 
        &filter, 
        DEVICE_NOTIFY_WINDOW_HANDLE
    );

WM_DEVICE_CHANGE メッセージを処理する関数を実装する必要があります。

bool
DevNotifier::onWM_DEVICECHANGE(WPARAM wparam, LPARAM lparam)
{
    DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*)lparam;
    // Note dbh will NOT always be valid, depending upon the value of wparam.

    if (wparam == DBT_DEVNODES_CHANGED) {
        // Do some stuff here
        return true;
    }
    else if (wparam == DBT_DEVICEARRIVAL) {
        DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lparam;
        if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
            DEV_BROADCAST_DEVICEINTERFACE* devinterface = 
                (DEV_BROADCAST_DEVICEINTERFACE*)hdr;

            // Do some stuff here
        }       
    }
    else if (wparam == DBT_DEVICEREMOVEPENDING) {
    }
    else if (wparam == DBT_DEVICEREMOVECOMPLETE) {
        HANDLE h = INVALID_HANDLE_VALUE;
        DEV_BROADCAST_HDR* phdr = (DEV_BROADCAST_HDR*) lparam;
        if (phdr->dbch_devicetype == DBT_DEVTYP_HANDLE) {
            DEV_BROADCAST_HANDLE* pdbh = (DEV_BROADCAST_HANDLE*) lparam;
            h = pdbh->dbch_handle;
        }
        else if (phdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
            DEV_BROADCAST_DEVICEINTERFACE* devinterface = 
                (DEV_BROADCAST_DEVICEINTERFACE*)phdr;

            // Do some stuff here
        }
        // Maybe do some stuff here too.
    }
    return false;
}

コンソール アプリケーションでは、Windows メッセージを機能させるためにメッセージ ポンプを実行する必要があります。アプリケーションがメッセージを待っている間に他のことをする必要がある場合は、それもここで処理する必要があります。

while (GetMessage(&message, NULL, 0, 0) > 0) {
  TranslateMessage(&message);
  DispatchMessage(&message);
}
于 2013-10-11T11:45:09.923 に答える