Reputation: 61
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?
Upvotes: 1
Views: 9368
Reputation: 4812
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);
}
Upvotes: 1
Reputation: 61
I have found out one more solution for this using devcon utility. It provides various commands to enable and disable usb devices.
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..
Upvotes: 1