2013-10-10 2 views
0

누구나 C/C++를 사용하여 USB 포트를 활성화 및 비활성화하는 방법을 알려줄 수 있습니까?USB 포트 활성화 및 비활성화

나는 이미 이렇게하는 한 가지 방법을 검색했습니다. 사용중인 Windows 레지스트리는 있지만 몇 가지 문제가 있습니다.

HKEY_LOCAL_MACHINE을 \ 시스템 \ CURRENTCONTROLSET 서비스 \ USBSTOR

변화를 차단 해제 4 세에 시작 값의 값 ---- ---- 그것은 창에 올바른 동작을 표시하지 않습니다

차단 \ 7. eg- 시작 값의 값을 4로 변경하면 usb 포트가 비활성화되지만 다시 활성화하려면 시스템을 다시 시작해야하고 모든 포트를 비활성화 한 후에 하나 더 사용하지 못하게 설정되어 있지만 이미 플러그인 된 포트를 사용할 수 있습니다. 장치.

다른 방법은 없나요?

+3

'Windows 7에서 올바르게 작동하지 않습니다.' "정교합니다. –

+0

@Raghav Guar 당신이 이것을 시도 했습니까? 레지스트리 편집기를 열고 HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ USBSTOR로 이동하고 4를 입력 한 다음 확인을 누릅니다. 작동합니까?그렇다면 win api를 사용하여 레지스트리 – Qwerty

+0

@ Qwerty로 작업 할 수 있습니다 : 자신의 방법을 사용했으며 제 질문에도 설명했습니다.이 방법은 Windows XP에서는 제대로 작동하지만 Windows 7에서는 제대로 작동하지 않습니다. –

답변

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 장치 용 prog 작성을위한 libusb-win32 라이브러리에 대해 들어 봤습니다.

그래서 아무도

이 여러분 모두 감사합니다

어떤 도움이 높게 평가 될 것입니다 .. .. 그것에 대해 생각을 가지고 않습니다 ..

+0

Libusb에서는 필터 드라이버를 설치하여 USB 장치와 통신 할 수 있습니다. 당신은 그걸로 USB 포트를 비활성화 할 수 없을거야. – Pete

+0

@ Pete : 답장을 보내 주셔서 감사합니다 ...하지만 한 가지 더 묻고 싶습니다 .. libusb-win32를 사용하여 장치를 시스템에 삽입하거나 시스템에서 제거 할 때 인터럽트를 얻을 수 있습니까? –

+0

그 기능이 없다고 생각합니다. RegisterDeviceNotification 등 사용 : http://msdn.microsoft.com/en-us/library/aa363431(VS.85).aspx – Pete

0

이 정말 질문 R.E.에 의견을 응답한다 장치 감지.

콘솔 응용 프로그램에서 숨겨진 창을 만듭니다.

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_에 알림을 등록 할 수 있습니다

이 예제는 HWND hidden_wnd_; 멤버 변수와 DevNotifier라는 클래스를 가지고 가정합니다.
예 :

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

당신이 창 메시지가 작동하도록하는 메시지 펌프를 실행해야 할 것입니다. 응용 프로그램이 메시지를 기다리는 동안 다른 작업을해야한다면 여기에서도 처리해야합니다.

while (GetMessage(&message, NULL, 0, 0) > 0) { 
    TranslateMessage(&message); 
    DispatchMessage(&message); 
}