1

Can anyone tell me how to enable and disable USB port using C/C++.

I have already searched one way to do this..using windows registry but there are some problems with it.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\USBSTOR

change the value of start value to 3----for unblock 4----block

It does not show correct behavior on windows 7. eg- when I change the value of start value to 4 it disable the usb ports but again for enabling we need to restart the system and one more thing after disabling all the ports are disabled but still we are able to use already plugged device.

Any other way to do it?

Raghav Guar
  • 61
  • 1
  • 8
  • 3
    `"It does not show correct behavior on windows 7.`" Elaborate. – Jonathon Reinhart Oct 10 '13 at 08:30
  • @Raghav Guar Did you you try this? Open the registry editor, navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR, Type 4, press OK. Does it work? If yes, you can use win api to work with registry – Qwerty Oct 10 '13 at 08:51
  • @Qwerty: I have used your way and I have described it in my question also.This method is working fine in windows xp but not in windows 7. – Raghav Guar Oct 10 '13 at 09:01
  • @jonathon Reinhart:when I change the value of start value to 4 it disable the usb ports but again for enabling we need to restart the system and one more thing after disabling all the ports are disabled but still we are able to use device,already plugged.. – Raghav Guar Oct 10 '13 at 09:04
  • found this thread: http://social.msdn.microsoft.com/Forums/vstudio/en-US/f7ef99eb-5d20-4dd1-9d1a-523ad14da0a9/disable-usb-?forum=csharpgeneral . Seems that it can be an issue of USB in use, that cannot be disabled? – graziano governatori Oct 10 '13 at 09:14
  • See http://stackoverflow.com/questions/365223/disable-usb-storage-devices for information about various ways to disable USB Storage port. – Richard Chambers Feb 20 '15 at 03:46
  • One thing to look at is whether you have administrator privileges or not. Under Windows 7 you can run a utility that will make a change to the HKEY_LOCAL_MACHINE however if the utility does not run with Administrator privileges then Windows 7 will do you a favor and silently create a clone of HKEY_LOCAL_MACHINE and make the change to the clone and not the actual Administrator level HKEY_LOCAL_MACHINE. – Richard Chambers Mar 02 '15 at 01:32

2 Answers2

1

I have found out one more solution for this using devcon utility. It provides various commands to enable and disable usb devices.

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

But it needs administrative privileges for running commands and I don't have source code for this.

So I want ask you all one thing.. I have heard about libusb-win32 library for writing prog for USB devices.

So does anybody have idea about it..

Any help will be highly appreciated..

Thank you all..

Raghav Guar
  • 61
  • 1
  • 8
  • Libusb allows you to talk to a usb device by installing a filter driver. You wont be able to disable the usb port with it. – Pete Oct 11 '13 at 07:11
  • @Pete: Thanks for the reply...But one more thing I want to ask ..Is it possible to get the interrupt when the device is inserted or removed from the system using libusb-win32. – Raghav Guar Oct 11 '13 at 08:05
  • I don't think it has features for that. Use RegisterDeviceNotification etc: http://msdn.microsoft.com/en-us/library/aa363431(VS.85).aspx – Pete Oct 11 '13 at 09:07
  • you can parse DEV_BROADCAST_DEVICEINTERFACE::dbcc_name to get the VID and PID of your device. The hardware ID will contain the string "\USB' and 'VID_1234' and 'PID_1234'. The numbers there will obviously change from device to device. – Pete Oct 11 '13 at 09:10
  • You may also want to register for notifications for specific interface GUIDs. I think you can see this in the inf file for your libusb device. – Pete Oct 11 '13 at 09:11
  • @Pete: Thanks for your reply...I have already seen that option that you have described using RegisterDeviceNotification() and process the messages DEVICE_CHANGE()...but the problem is that how to implement these methods in my code(I am developing console application and in RegisterDeviceNotification() we have to register top level window ) that I am writing...I am finding difficulties..Can you please halp me..it will be highly appreciated... – Raghav Guar Oct 11 '13 at 09:13
  • You can create a hidden window and use its handle. – Pete Oct 11 '13 at 09:21
  • @Pete:I have tried but I was not able to integrate RegisterDeviceNotification() and Device_change()..could you help me.. – Raghav Guar Oct 11 '13 at 09:43
  • @pete:there is a link for hardware detection...http://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal Now I want to take out the particular code and embed into my program..But I am finding difficulties.. – Raghav Guar Oct 11 '13 at 09:47
1

This is really answering comments on the question r.e. device detection.

Create a hidden window in your console application.

This example assumes you have a class called DevNotifier, with an HWND hidden_wnd_; member variable:

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

You can register for notifications on 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
    );

You'll need to implement the function to deal with the WM_DEVICE_CHANGE messages:

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

In your console application you are going to have to run a message pump to get windows messages to work. If you have got other stuff to do while the application is waiting for messages then you'll need to also handle that here.

while (GetMessage(&message, NULL, 0, 0) > 0) {
  TranslateMessage(&message);
  DispatchMessage(&message);
}
Pete
  • 4,784
  • 26
  • 33