启用和禁用USB端口

时间:2013-10-10 08:28:38

标签: c++ c windows

任何人都可以告诉我如何使用C / C ++启用和禁用USB端口。

我已经搜索了一种方法来执行此操作..使用Windows注册表但是它存在一些问题。

HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \服务\ USBSTOR

将unblock的起始值更改为3 ---- 4 ----块

它在Windows 7上没有显示正确的行为。例如 - 当我将起始值的值更改为4时,它会禁用usb端口但是再次启用我们需要重新启动系统,禁用所有端口后再禁用一些东西,但我们仍然可以使用已经插入的设备。

还有其他办法吗?

2 个答案:

答案 0 :(得分:0)

我已经使用devcon实用程序找到了另一个解决方案。 它提供了各种命令来启用和禁用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库。

所有人都有这个想法..

任何帮助都将受到高度赞赏..

谢谢大家..

答案 1 :(得分:0)

这真的回答了关于r.e.的问题的评论。设备检测。

在控制台应用程序中创建一个隐藏窗口。

此示例假设您有一个名为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_上注册通知 e.g。

    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);
}