Russian Qt Forum
Сентябрь 22, 2024, 16:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [windows] список USB накопителей  (Прочитано 13683 раз)
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« : Август 26, 2009, 16:03 »

Под виндз не писал уже несколько лет Улыбающийся Как можно определить список подключенных USB накопителей, и информацию о них? В Qt форме необходимо вывести их буквы и метки (vendor+model если метки нет). Как это можно замутить? Кроссплатформенность неважна, программа будет только для виндз.
Записан
crackedmind
Гость
« Ответ #1 : Август 26, 2009, 16:16 »

Почитай вот тут: http://msdn.microsoft.com/en-us/library/aa365730(VS.85).aspx
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #2 : Август 26, 2009, 16:17 »


угу, что-то похожее на правду. Спасибо.

Доп. А как узнать более подробную информацию об устройстве - vendor, model, bus и т.д.? Наподобие как в Linux через HAL.
« Последнее редактирование: Август 26, 2009, 17:53 от AX » Записан
crackedmind
Гость
« Ответ #3 : Август 26, 2009, 18:35 »

Тут похоже надо копать в сторону Win DDK, средствами SDK это не решить.

p.s.
нашел программку, которая выводит различную инфу про разделы. http://www.winsim.com/diskid32/ Сорцы прилагаются.
Записан
zenden
Гость
« Ответ #4 : Август 26, 2009, 19:04 »

можешь посмотреть исходники unetbootin
Написана на Qt4, каким-то образом получает список USB накопителей и винде, и в линуксе.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #5 : Август 26, 2009, 19:33 »

спасибо, буду разбираться
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #6 : Август 26, 2009, 22:27 »

вобщем изыскания такие - unetbootin использует самый простой способ - берёт список дисков и отсеивает из них не-removable, это я уже и сам сделал Улыбающийся

diskid32 делает всё через DDK, через DeviceIoControl. Проблема в том, что она показывает инфу только о жёстких дисках, а об USB флешках - нет (флешка вставлена). Глядя на код вижу, что там перебираются устройства по маске "\\\\.\\Scsi%d:" от 0 до 16. Может, USB накопители по другой маске индексируются?
Записан
ритт
Гость
« Ответ #7 : Август 26, 2009, 23:27 »

конечно.
выведи dos-имена всех дисков - увидишь разницу...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Август 27, 2009, 07:55 »

А не проще ли читать реестр на предмет нужной информации? Пусть "ядро" самой винды берет инфу и кладет в реестр!

А Вы уже из рееестра! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Hordi
Гость
« Ответ #9 : Август 27, 2009, 13:51 »

Вот тут я вендора и продукт айди получаю - ищи "SELECT * FROM Win32_USBControllerDevice".

Код:
void DrivesEnumerator::setDriveInfoEx(std::vector<DriveInfo>& rez,bool hasUSB)
{
  if(rez.empty()){
    return;
  }

  HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); //COINIT_APARTMENTTHREADED

  bool uninit = (S_OK==hres);

  IWbemLocator *pLoc = NULL;
  IWbemServices *pSvc = NULL;
  IEnumWbemClassObject* pEnumerator = NULL;
  IWbemClassObject *pclsObj = NULL;

  std::map<unicodeString,int> mm; //PnP-SN,index

  do{
    if(uninit){
      hres = CoInitializeSecurity(NULL,-1,NULL,NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,EOAC_NONE,NULL);

      if(FAILED(hres)){
        break;
      }
    }

    hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID*)&pLoc);

    if(FAILED(hres)){
      break;
    }

    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,0,NULL,0,0,&pSvc);
     
    if(FAILED(hres)){
      break;
    }

    hres = CoSetProxyBlanket(
      pSvc,
      RPC_C_AUTHN_WINNT,
      RPC_C_AUTHZ_NONE,
      NULL,
      RPC_C_AUTHN_LEVEL_CALL,
      RPC_C_IMP_LEVEL_IMPERSONATE,
      NULL,
      EOAC_NONE
    );

    if(FAILED(hres)){
      break;
    }

    VARIANT v;
    HRESULT hr;

    //retrieving Drive's name
    hres = pSvc->ExecQuery( bstr_t("WQL"),
      bstr_t("SELECT * FROM Win32_DiskDrive"), //Win32_DiskDrive, PhysicalMedia , Win32_DiskDrivePhysicalMedia
      WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
      NULL,&pEnumerator);
     
    if(FAILED(hres)){
      break;
    }

    while(pEnumerator){
      ULONG uReturn = 0;

      hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

      if(0 == uReturn){
        break;
      }

      if(S_OK == (hr = pclsObj->Get(L"Index", 0, &v, 0, 0))){

        for(unsigned i=0;i<rez.size();++i){
          adf::gui::DriveInfo& r = rez[i];
          if(r.driveNumber() == (int)v.uintVal){

            if(S_OK == (hr = pclsObj->Get(L"Model", 0, &v, 0, 0))){
              r._name = v.bstrVal;
              VariantClear(&v);
            }
           
            if(!hasUSB){
              break;
            }
            if(S_OK != (hr = pclsObj->Get(L"InterfaceType", 0, &v, 0, 0))){
              break;
            }

            //SCSI,HDC,IDE,USB,1394
            bool ok = (unicodeString(v.bstrVal)==STRING_CONST("USB"));
            VariantClear(&v);
            if(!ok){
              break;
            }
            if(S_OK != (hr = pclsObj->Get(L"PNPDeviceID", 0, &v, 0, 0))){
              break;
            }
            unicodeString s = (v.bstrVal);
            VariantClear(&v);

            unicodeString::size_type ps, pos = s.rfind(UNICHR('\\'));
            if(unicodeString::npos!=pos){
              ps = s.find(UNICHR('&'),++pos);
              if(unicodeString::npos!=ps){
                mm[unicodeString(s.substr(pos,ps-pos))] = i;
              }
            }

            break;
          }
        }

        VariantClear(&v);
      }
    }

    if(!hasUSB){
      break;
    }

    if(pEnumerator){
      pEnumerator->Release();
    }

    //retrieving USB VendorID,ProductID
    hres = pSvc->ExecQuery( bstr_t("WQL"),
      bstr_t("SELECT * FROM Win32_USBControllerDevice"),
      WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
      NULL,&pEnumerator);
     
    if(FAILED(hres)){
      break;
    }

    while(pEnumerator){
      ULONG uReturn = 0;

      hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

      if(0 == uReturn){
        break;
      }

      if(S_OK == (hr = pclsObj->Get(L"Dependent", 0, &v, 0, 0))){

        unicodeString s = v.bstrVal;
        VariantClear(&v);
       
        //"USB\\VID_058F&PID_6387\\GXP25EUB"
        unicodeString str( STRING_CONST("=\"USB\\\\VID_") );
        unicodeString::size_type ps, pos = s.find(str);
        if(pos==unicodeString::npos){ //extract VendorID, ProductID, SerialNumber(for searching)
          continue;
        }
        pos += str.size();
        str = STRING_CONST("&PID_");
        ps = s.find(str,pos);
        if(unicodeString::npos==ps){
          continue;
        }

        unicodeString VID( s.substr(pos,ps-pos) );
        ps += str.size();
       
        //extract PID
        str = STRING_CONST("\\\\");
        pos = s.find(str,ps);
        if(unicodeString::npos==ps){
          continue;
        }
        unicodeString PID( s.substr(ps,pos-ps) );
        pos += str.size();
       
        if(unicodeString::npos != s.find(STRING_CONST("&"),pos)){
          continue;
        }

        //extract SerialNumber
        ps = s.find(STRING_CONST("\""),pos);
        if(unicodeString::npos==ps){
          continue;
        }

        unicodeString SN( s.substr(pos,ps-pos) );

        //set founded information
        std::map<unicodeString,int>::iterator it = mm.find(SN);
        if(it!=mm.end()){
          DriveInfo& r = rez[it->second];
          r._vendorID = VID;
          r._productID = PID;
          r._serial = SN;
        }
      }
    }

  }while(0);

  if(pSvc){
    pSvc->Release();
  }
  if(pLoc){
    pLoc->Release();
  }
  if(pEnumerator){
    pEnumerator->Release();
  }
  if(pclsObj){
    pclsObj->Release();
  }

  if(uninit){
    CoUninitialize();
  }
}
Записан
NurMKM
Гость
« Ответ #10 : Март 13, 2013, 09:08 »

Вот тут я вендора и продукт айди получаю - ищи "SELECT * FROM Win32_USBControllerDevice".

Всем привет.

Hordi, у меня такая же задача найти вендор ид и прод ид USB флешки. Я не знаком с QT. Я вставил ваш код но у меня ссыпаются ошибки. Можете вы проконсультировать.
#include "stdafx.h"
#include <iostream>
#include <WTypes.h>
using namespace std;
#define _WIN32_DCOM
#include <comdef.h>
#include <Wbemidl.h>

# pragma comment(lib, "wbemuuid.lib") 
Я добавил эти библиотеки может еще какие то надо, что бы решить эти ошибки.
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(178): error C2065: 'r' : undeclared identifier
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(178): error C2228: left of '._name' must have class/struct/union
1>          type is ''unknown-type''
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(182): error C2065: 'hasUSB' : undeclared identifier
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(190): error C2446: '==' : no conversion from 'const char *' to 'BSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(190): error C2440: '==' : cannot convert from 'const char [4]' to 'BSTR'
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(198): error C2065: 'unicodeString' : undeclared identifier
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(198): error C2146: syntax error : missing ';' before identifier 's'
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(198): error C2065: 's' : undeclared identifier
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(201): error C2653: 'unicodeString' : is not a class or namespace name
1>c:\users\user\desktop\c++\projects\wmi_device_pid\wmi_device_pid\wmi_device_pid.cpp(201): error C2065: 'size_type' : undeclared identifier   
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #11 : Март 13, 2013, 21:32 »

добавляю namespace, который я использовал в конечном проекте. Функция Ddk::drives(num) возвращает подключённые USB накопители, размер которых минимум num байт. Перед работой нужно вызвать Ddk::init()
Записан
lolbla2
Гость
« Ответ #12 : Март 15, 2013, 10:16 »

А как насчёт посмотреть в сторону libusb?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #13 : Март 15, 2013, 11:40 »

Под Windows проще всего использовать энумерацию устройств конкретного класса через SetupAPI:

SetupDiGetDeviceRegistryProperty + SetupDiOpenDevRegKey + SetupDiGetClassDevs + SetupDiEnumDeviceInfo

см. MSDN и гугл. Улыбающийся

UPD: И никаких заголовков и прочего от WDK не нужно.
Записан

ArchLinux x86_64 / Win10 64 bit
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 23.