Дорого времени суток!!! Собственно весь вопрос в названии темы. Драйвер disk.sys для каждого логического диска создает свой Device_object для управления диском(на сколько я знаю, если не прав сильно не пинайте). Так вот как можно получить всякую полезную инфу о диске имея его Device_object.( конкретно интересует VID&PID)???
Под VID&PID я имел ввиду следующее: У каждого диска есть свой уникальный номер. Мне, конкретно, нужно узнавать уникальный номер съемного носителя - флэшки. В системе он выглядит (у моей флэшки) - USB\VID_058&PID_6387\XL19S8UG. Это как я понимаю уникальный номер который присваивает завод изготовитель. Так вот как я его могу получить по Device_object???
по теме не знаю могу дать сэмпл перебора дерева устройств, при желании его можно перенести в кернел. если это чем-нибудь поможет: Код (Text): #include "stdafx.h" #include "1.h" #include "tfile.h" #include "cfgmgr32.h" #pragma comment(lib, "Setupapi.lib") RETURN_TYPE error_code= CR_SUCCESS; void DumpNode(int level, HANDLE hFile, DEVINST nDevNode, HMACHINE hMachine); void DumpNodeInfo(int level, HANDLE hFile, DEVINST nDevNode, HMACHINE hMachine); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. DEVINST nRootInst; HMACHINE hLocalMachine; HANDLE hFile= NULL; try { hFile= TCreateFile("devlist.txt", TRUE); hLocalMachine= (HMACHINE)NULL; error_code= CM_Locate_DevNode_Ex(&nRootInst, NULL, CM_LOCATE_DEVNODE_NORMAL, hLocalMachine); if(error_code!=CR_SUCCESS) throw "Cannot locate root devnode"; DumpNodeInfo(0, hFile, nRootInst, hLocalMachine); DumpNode(0, hFile, nRootInst, hLocalMachine); } catch(char *str) { char errstr[1000]; sprintf(errstr, "%s, error code: %d", str, error_code); MessageBox(NULL, errstr, "An error was occuired", 0); } catch(...) { } if(TCheckFileHandle(hFile)) TCloseFlie(hFile); return 0; } void DumpNode(int level, HANDLE hFile, DEVINST nDevNode, HMACHINE hMachine) { DEVINST nDevInst; error_code= CM_Get_Child_Ex(&nDevInst, nDevNode, 0, hMachine); if(error_code!=CR_SUCCESS) if(error_code!=CR_NO_SUCH_DEVNODE) throw "Cannot locate child devnode"; while(error_code==CR_SUCCESS) { DumpNodeInfo(level+1, hFile, nDevInst, hMachine); DumpNode(level+1, hFile, nDevInst, hMachine); error_code= CM_Get_Sibling_Ex(&nDevInst, nDevInst, 0, hMachine); if(error_code!=CR_SUCCESS) if(error_code!=CR_NO_SUCH_DEVNODE) throw "Cannot locate child devnode"; } } void DumpNodeInfo(int level, HANDLE hFile, DEVINST nDevNode, HMACHINE hMachine) { TCHAR tszDeviceId[0x1000]; TCHAR tszClassId[0x1000]; TCHAR tszNameId[0x1000]; TCHAR tszPhDevNameId[0x1000]; TCHAR tszNumber[0x10]; BOOL isName= TRUE; BOOL isPhDevName= TRUE; BOOL isClass= TRUE; ULONG ulSize; int i; error_code= CM_Get_Device_ID_Ex(nDevNode, tszDeviceId, sizeof(tszDeviceId), 0, hMachine); if(error_code!=CR_SUCCESS) throw "Cannot get device id"; ulSize= sizeof(tszClassId); error_code= CM_Get_DevNode_Registry_Property_Ex(nDevNode, CM_DRP_CLASS, NULL, tszClassId, &ulSize, 0, hMachine); if(error_code!=CR_SUCCESS) { isClass= FALSE; if(error_code!=CR_NO_SUCH_VALUE && error_code!=CR_BUFFER_SMALL) throw "Cannot get device class"; } ulSize= sizeof(tszNameId); error_code= CM_Get_DevNode_Registry_Property_Ex(nDevNode, CM_DRP_FRIENDLYNAME, NULL, tszNameId, &ulSize, 0, hMachine); if(error_code!=CR_SUCCESS) { isName= FALSE; if(error_code!=CR_NO_SUCH_VALUE && error_code!=CR_BUFFER_SMALL) throw "Cannot get device friendly name"; } if(level) { ulSize= sizeof(tszPhDevNameId); error_code= CM_Get_DevNode_Registry_Property_Ex(nDevNode, CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME, NULL, tszPhDevNameId, &ulSize, 0, hMachine); if(error_code!=CR_SUCCESS) { isPhDevName= FALSE; if(error_code!=CR_NO_SUCH_VALUE && error_code!=CR_BUFFER_SMALL) throw "Cannot get physical device object name"; } } else { isPhDevName= FALSE; } for(i= 0; i<level; i++) TWriteFile(hFile, _T("\t"), 0, (DWORD)_tcslen(_T("\t"))*sizeof(TCHAR), TRUE); _stprintf(tszNumber, "%d. ", level); TWriteFile(hFile, tszNumber, 0, (DWORD)_tcslen(tszNumber)*sizeof(TCHAR), TRUE); TWriteFile(hFile, tszDeviceId, 0, (DWORD)_tcslen(tszDeviceId)*sizeof(TCHAR), TRUE); if(isName || isClass || isPhDevName) TWriteFile(hFile, _T(" ("), 0, (DWORD)_tcslen(_T(" ("))*sizeof(TCHAR), TRUE); if(isName) { TWriteFile(hFile, _T("\""), 0, (DWORD)_tcslen(_T("\""))*sizeof(TCHAR), TRUE); TWriteFile(hFile, tszNameId, 0, (DWORD)_tcslen(tszNameId)*sizeof(TCHAR), TRUE); TWriteFile(hFile, _T("\""), 0, (DWORD)_tcslen(_T("\""))*sizeof(TCHAR), TRUE); } if(isName && (isPhDevName || isClass)) TWriteFile(hFile, _T(", "), 0, (DWORD)_tcslen(_T(", "))*sizeof(TCHAR), TRUE); if(isPhDevName) TWriteFile(hFile, tszPhDevNameId, 0, (DWORD)_tcslen(tszPhDevNameId)*sizeof(TCHAR), TRUE); if((isName || isPhDevName) && isClass) TWriteFile(hFile, _T(", "), 0, (DWORD)_tcslen(_T(", "))*sizeof(TCHAR), TRUE); if(isClass) TWriteFile(hFile, tszClassId, 0, (DWORD)_tcslen(tszClassId)*sizeof(TCHAR), TRUE); if(isName || isClass || isPhDevName) TWriteFile(hFile, _T(")"), 0, (DWORD)_tcslen(_T(")"))*sizeof(TCHAR), TRUE); TWriteFile(hFile, _T("\r\n"), 0, (DWORD)_tcslen(_T("\r\n"))*sizeof(TCHAR), TRUE); }
Если под Device_object имеется ввиду объект созданный disk.sys, то скорее всего никак. Для флешек создается три PnP-узла (device node). Код (Text): Запоминающее устройство для USB PDO:usbhub FDO:usbstor Дисковый накопитель PDO:usbstor FDO:Disk Универсальный том PDO:Disk FDO:- В отладчике этот кусок PnP дерева для моей флешки выглядит так: Код (Text): kd> !DevNode 8119ff28 1 DevNode 0x8119ff28 for PDO 0x811afe90 Parent 0x811a0d48 Sibling 0000000000 Child 0x8116ad68 InstancePath is "USB\Vid_0c76&Pid_0005\6&38c5a47&0&1" ServiceName is "USBSTOR" Flags (0x00040458) DNF_PROCESSED, DNF_ENUMERATED, DNF_ADDED, DNF_NO_RESOURCE_REQUIRED, DNF_STARTED CapabilityFlags (0x00000010) Removable DevNode 0x8116ad68 for PDO 0x8117aed0 Parent 0x8119ff28 Sibling 0000000000 Child 0x811c8aa8 InstancePath is "USBSTOR\Disk&Ven_JetFlash&Prod_TS128MJF2A&Rev_1.00\7&311ad6ac&0" ServiceName is "disk" Flags (0x00040458) DNF_PROCESSED, DNF_ENUMERATED, DNF_ADDED, DNF_NO_RESOURCE_REQUIRED, DNF_STARTED DevNode 0x811c8aa8 for PDO 0x8119bd90 Parent 0x8116ad68 Sibling 0000000000 Child 0000000000 InstancePath is "STORAGE\RemovableMedia\8&2aa6674d&0&RM" TargetDeviceNotify List - f 0xe24f0c88 b 0xe24f0c88 Flags (0x00040458) DNF_PROCESSED, DNF_ENUMERATED, DNF_ADDED, DNF_NO_RESOURCE_REQUIRED, DNF_STARTED CapabilityFlags (0x00000180) SilentInstall, RawDeviceOK А стеки этих нод вот: Код (Text): kd> !devstack 0x811afe90 !DevObj !DrvObj !DevExt ObjectName 811e5bd0 \Driver\USBSTOR 811e5c88 00000023 > 811afe90 \Driver\usbhub 811aff48 USBPDO-5 !DevNode 8119ff28 : DeviceInst is "USB\Vid_0c76&Pid_0005\6&38c5a47&0&1" ServiceName is "USBSTOR" kd> !devstack 0x8117aed0 !DevObj !DrvObj !DevExt ObjectName 81164ca0 \Driver\Diskperf 81164d58 81164ea0 \Driver\PartMgr 81164f58 811debd0 \Driver\Disk 811dec88 DR4 > 8117aed0 \Driver\USBSTOR 8117af88 00000024 !DevNode 8116ad68 : DeviceInst is "USBSTOR\Disk&Ven_JetFlash&Prod_TS128MJF2A&Rev_1.00\7&311ad6ac&0" ServiceName is "disk" kd> !devstack 0x8119bd90 !DevObj !DrvObj !DevExt ObjectName > 8119bd90 \Driver\Disk 8119be48 DP(1)0-0+5 !DevNode 811c8aa8 : DeviceInst is "STORAGE\RemovableMedia\8&2aa6674d&0&RM" usbstor тут является "водоразделом". Всё что выше него к USB никак не относится. Он как раз и занимается переводом SCSI команд в URB. Поэтому все пакеты, которые гуляют во втором и третьем стеке к USB никакого отношения не имеют. А вот в первом стеке из-под usbstor уже идут USB-related пакеты. Поэтому если под Device_object имеется ввиду любой девайс из первого стека, то можно запросить у хаба дескриптор USB девайса. Конкретые IOCTL есть в исходниках DDK\src\wdm\usb\usbview. Их можно юзать и из драйвера. Если эти IOCTL пустить по второму/третьему стеку, то они просто их не поймут и возвратять ошибку. А VID и PID достается из дескриптора USB девайса. VID - Vendor ID. Покупается производителем у USB комитета на usb.org PID - Product ID. Самостоятельно присваивается производителем USB девайса. XL19S8UG в данном случае серийный номер флешки. Хранится в самом девайсе как строка, индекс которой в DeviceDescriptor.iSerialNumber. Для моей флешки UVCView выдает такой DeviceDescriptor. Код (Text): bLength: 0x12 bDescriptorType: 0x01 bcdUSB: 0x0110 bDeviceClass: 0x00 bDeviceSubClass: 0x00 bDeviceProtocol: 0x00 bMaxPacketSize0: 0x40 idVendor: 0x0C76 idProduct: 0x0005 bcdDevice: 0x0100 iManufacturer: 0x01 iProduct: 0x02 iSerialNumber: 0x00 Лажёвая флешка без серийника, хотя по спецификации должен быть ;) bNumConfigurations: 0x01 ЗЫ: Ух ну и запарился я всё это писАть Тут тебе надо много покурить разных доков. Тема сложная - курить придется долго. Начни с раздела по USB в DDK. Там, например есть диаграммы USB Driver Stack for Windows 2000 и USB Driver Stack for Windows XP and Later.
МегаРеспект вам Four-F Запасусь бамбуком и буду раскуривать))))) Благодаря вашим вставкам возникла одна гениальная) идея. Если получиться обязательно отпишуся!!!!!!
Four-F Покурил, покурил.... вот только не гелче....((( Мне нужно итого получить строку вида USB\Vid_0c76&Pid_0005\6&38c5a47&0&1 Код (Text): kd> !devstack 0x811afe90 !DevObj !DrvObj !DevExt ObjectName 811e5bd0 \Driver\USBSTOR 811e5c88 00000023 > 811afe90 \Driver\usbhub 811aff48 USBPDO-5 !DevNode 8119ff28 : DeviceInst is "USB\Vid_0c76&Pid_0005\6&38c5a47&0&1" ServiceName is "USBSTOR" Я так понимаю мне нужна строка DeviceInst из команды DevNode. Но как ее получить ума не приложу...... PS: через IoGetDeviceProperty с параметром DevicePropertyHardwareID могу получить строку вида USB\Vid_0c76&Pid_0005\Rev_0100 Только не то это......
В ядре, к сожалению, никак. Документированного способа нет. Чтоб у нас не было разночтений в терминологии.... "USB\Vid_0c76&Pid_0005\6&38c5a47&0&1" - Device instance ID http://msdn2.microsoft.com/en-us/library/ms791083.aspx#998b4565-9479-4d9d-b3d1-fd0c947829c5 "USB\Vid_0c76&Pid_0005&Rev_0100" - Первая строка в Hardware IDs http://msdn2.microsoft.com/en-us/library/ms791083.aspx#df9964a2-fa06-4bf1-97c9-9fbc986816ec
Можешь попробовать поискать в конфе http://www.osronline.com/page.cfm?name=search смутно помню, что там это (получение device instance id), вроде, обсуждалось.
Пробую перехватывать IRP_MN_QUERY_ID. На выходе в случаи успеха в IoStatus.Information должен вернуться указатель на буфер с информацией. Код (Text): On success, a driver sets Irp->IoStatus.Information to a WCHAR pointer that points to the requested information. On error, a driver sets Irp->IoStatus.Information to zero. Возвращает например "00000190" вот только ни как не могу найти сам буфер с информацией. ((((((
я хучу в DRIVER_OBJECT IRP_MJ_PNP отлавливаю IRP с IRP_MN_QUERY_ID передаю их дальше и смотрю что на выходе... Завершается IRP без ошибок вроде, все чики-пуки вот только буфер какой то странный((((
Four-F Как всегда вы правы)))) помог все тотже softice.... Я обращался по видимому уже к завершенному irp..... Еще вопром по этой теме: с помощью IoGetDeviceProperty с параметром DevicePropertyDeviceDescription я получаю массив данных. В проге DeviceLock при занесении в базу флэшки по мимо VID&PID записывается еще и этот дескриптор устройства. Я так понимаю это тоже своего рода уникальный номер для каждого устройства??? Что вы думаете по этому поводу?
Это не "массив данных" и не "дескриптор устройства" и тем более не "своего рода уникальный номер". Это просто некая чисто описательная строка типа "Bluetooth 2.0 USB Device" или "USB PC Camera", которая по большому счёту вообще ничего не значит. Если DeviceLock её и запоминает, то только затем, чтоб показать юзеру. Больше ни на что она не годится.