Як можна дізнатися модель USB-устрою
Серійний номер USB-пристрою визначаю так: var VolumeName, FileSystemName : array [0..MAX_PATH-1] of Char; VolumeSerialNo : DWord; MaxComponentLength,FileSystemFlags: Cardinal; begin GetVolumeInformation("J:\",VolumeName,MAX_PATH,@VolumeSerialNo, MaxComponentLength,FileSystemFlags, FileSystemName,MAX_PATH); Memo1.Lines.Add("SerialNo = $"+IntToHex(VolumeSerialNo,8)); А як можна дізнатися (додатково) його модель? (Пр.: "Kingston DataTraveler (DTI/512)")
←→Правильний Вася (2007-06-14 15:26) [1]
це в реєстрі покопатися LocalMachine\system\currentcontrolset
←→Ral'f (2007-06-14 16:04) [2]
і на тому спасибі!
←→Ral'f (2007-06-15 13:49) [3]
Так, після форматування VolumeSerialNo змінюється (
Спробував я пошукати в реєстрі - знайшов! Щось типу ID пристроїв там, правда, є! Але тоді як зв'язати в програмі - запис у реєстрі і букву диска?
Тепер питання навіть – як взагалі можна ідентифікувати зовнішній пристрій (будь то флешка, плекстор чи карта пам'яті)?
Ось тобі на допомогу. Саме визначається і тип пристрою, і модель, і серійний номер.
IdeInfo2 - отримання різної інформації про диск IDE(http://home.earthlink.net/
akonshin/files/IdeInfo2.zip, 30 Jul 2000, 27K, D3+) За допомогою SMART Ioctl API можна отримати модель, версію прошивки, серійний номер, стан різних лічильників IDE вінчестера. Перевірялося на Windows 98, Windows NT 4.0 та Windows 2000.
IdeSN – отримання серійного номера першого IDE диска(http://home.earthlink.net/
akonshin/files/IdeSN.zip, 30 Jul 2000, 4K, D3+) Приклад, що показує, як отримати серійний номер першого IDE вінчестера.Перевірялося на Windows 98, Windows NT 4.0 та Windows 2000.
IdeSN2 - отримання серійного номера першого IDE диска(новий приклад) (http://home.earthlink.net/
akonshin/files/IdeSN2.zip, 22 Oct 2003, 5K, D5+) Приклад, що показує як отримати серійний номер першого IDE вінчестера. Перевірялося на Windows 98, Windows NT 4.0, Windows 2000 та Windows XP.
Так, забув відзначити. USB-накопичувачі (флешки, USB-гвинти) в системі стають жорсткими дисками, що знімаються, тому до них можна звертатися через CreateFile, отже, вищевказані приклади до них застосовні.
←→Ral'f (2007-06-15 15:32) [6]
> IdeInfo2 - отримання різної інформації про IDE диск- те, що потрібно, АЛЕ в XP не працює (а зараз в основному скрізь ця ОС)
> IdeSN2 - отримання серійного номера першого IDE диска- в першому, якраз, у мене потреби і немає!
←→Ral'f (2007-06-15 15:33) [7]
У мене все працює під ХР. Нещодавно перевіряв та брав звідти деякі речі для своєї проги.
←→Ral'f (2007-06-15 21:37) [9]
У мене хард на комп'ютері розбитий на два розділи: С і D Коли я пишу: if Win32Platform=VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000 Str(ControllerNumber,s); hDevice := CreateFile(PChar("\\.\С:"), // або D підключаю flash, пишу “F” і нічого не отримую!
За допомогою цих кодів можна отримати інформацію лише про внутрішні пристрої: HDD, DVD-ROM...
Чи щось треба дописати, щоб він розумів і зовнішні (usb)?
P.S. спробував і IdeInfo2, і IdeSN2!
Я ж написав, що всі флеш-накопичувачі стають знімними жорсткими дисками. Значить звертатися до них треба неCreateFile(PChar("\\.\С:") , а як до фізичного пристрою, тобто CreateFile(PChar("\\.\PhysicalDriveХ") ), де Х - номер фічеського пристрою.
Я ж написав, що всі флеш-накопичувачі стають знімними жорсткими дисками. Значить звертатися до них треба не CreateFile(PChar("\\.\С:") , а як до фізичного пристрою, тобто CreateFile(PChar("\\.\PhysicalDriveХ")), де Х - номер фізичного пристрою.
←→Ral'f (2007-06-16 08:54) [12]
> до них треба не CreateFile(PChar("\\.\С:"), а як до фізичного пристрою
Думаєш, я не пробував.
Знайди книгу "Інтерфейс USB практика використання та програмування" Автор: Павло Агуров. Видавець: Санкт-Петербург "БХВ-Петербург" 2005
- там майже все про USB
←→Ral'f (2007-06-16 12:56) [14]
Так і доведеться зробити! Сподівався по-швиденькому. :-)))
Поки я, напевно, використовуватиму мітку тома, а там дивишся - можу що вичитаю!
Щоправда, поки що шукав неодноразово зустрічав повідомлення про NoName пристрої, начебто від серійників у всьому світі зараз відмовляються. Тож може й зв'язуватися не варто!
Шукане можна отримати, приблизно, так: Весь код не наводжу, т.к. його дуже складно висмикнути з проекту. Опишу тільки підводні камені, з якими я зіткнулася Перша проблема: невідповідність розміру параметрів структур із заголовних файлів С++ з Delphi. Тут мій варіант її вирішення(не факт, що правильний, але робітник :) Змінювати закоментованість не рекомендується :) Я віддала перевагу не скрізь його( а ввести дод. поле _Fill: array[0..2 ] of Byte, в _STORAGE_DEVICE_DESCRIPTOR і змінити розмірність AdditionalParameters: array[0..9] of Byte у STORAGE_PROPERTY_QUERY бо необхідно було підтримати"сумісність розмірів» і в др. запитах і структурах. type // PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE; _STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, // Отримує дескриптор PropertyExistsQuery, // Використовується для перевірки, чи підтримується дескриптор PropertyMaskQuery, // Використовується для отримання маски записуваних полів у дескрипторі PropertyQueryMaxDefined); // Використовується для перевірки значення STORAGE_QUERY_TYPE = _STORAGE_QUERY_TYPE; //
тип // PSTORAGE_PROPERTY_ > _STORAGE_PROPERTY_ > STORAGE_PROPERTY_ >//
тип PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY; _STORAGE_PROPERTY_QUERY = упакований запис PropertyId: STORAGE_PROPERTY_ID; Тип запиту: STORAGE_QUERY_TYPE; Додаткові параметри: array[0..9] of Byte; кінець; STORAGE_PROPERTY_QUERY = _STORAGE_PROPERTY_QUERY;
тип PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE; _STORAGE_BUS_TYPE = (BusTypeUnknown = 0, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394, BusTypeSsa, BusTypeFibre, BusTypeUsb, BusTypeRAID, BusTypeiScsi, BusTypeSas, Bus TypeSata, BusTypeMaxReserved = $7F); STORAGE_BUS_TYPE = _STORAGE_BUS_TYPE;
Розібравшись з розмірами полів, перейшовши до спроби отримати, потрібні нам дані: Наступний сюрприз: за нашим запитом, якщо ми задали занадто маленький буфер для прийому даних, мало того, що цей поросенок (DeviceIoControl :) вірне Правда, так ще і GetLastError повертає нам ERROR_SUCCESS :) У нашому запиті значення ERROR_MORE_DATA і ERROR_INSUFFICIENT_BUFFER, GetLastError, чому-то видавати не хоче :) Схема того, як я намагалася боротися з цим "все в порядке" нижче.
const IOCTL_STORAGE_QUERY_PROPERTY = ((IOCTL_STORAGE_BASE shl 16) або (FILE_ANY_ACCESS shl 14) або ($0500 shl 2) абоMETHOD_BUFFERED); const DEVICE_DESCRIPTOR_INC = 512 - SizeOf(STORAGE_DEVICE_DESCRIPTOR);
function StorageQueryProperty(const hDevice: THandle; var pDescript: PSTORAGE_DEVICE_DESCRIPTOR; var cbDescript, cbReturned: DWord): DWord; var PropQuery: STORAGE_PROPERTY_QUERY; begin FillChar(PropQuery, SizeOf(STORAGE_PROPERTY_Q) UERY), 0); PropQuery.Property > PropQuery.QueryType := PropertyStandardQuery;
while DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, @PropQuery, SizeOf(STORAGE_PROPERTY_QUERY), pDescript, cbDescript, cbReturned, nil) do begin Result := GetLastError; case Результат ERROR_SUCCESS: if (pDescript.Size >= cbReturned) then begin cbDescript := pDescript.Size + DEVICE_DESCRIPTOR_INC; ReallocMem(pDescript, cbDescript); end else Break; // ERROR_MORE_DATA: // begin // якщо cbReturned > cbDescript then cbDescript := cbReturned else inc(cbDescript, IO_BUFFER_SIZE_INC); // ReallocMem(pDescript, cbDescript); // end; // ERROR_INSUFFICIENT_BUFFER: // begin / / inc(cbDescript, IO_BUFFER_SIZE_INC); // ReallocMem(pDescript, cbDescript); // end; // else Break; Вот, вроде и все. Разобраться со смещениями в STORAGE_DEVICE_DESCRIPTOR і перевести наші дані на "людський язик" оставляю у вигляді домашнього завдання :) P.S. Видергивалось и подгонялось "на коленке", так что строго не судить. Но принцип зберігся :) Вот кусочек, повертаемых даних: RemovableMedia: True CommandQueueing: False BusType: BusTypeUsb VendorId: C-ONE-5.0 ProductId: 128MB Aqua Редакція продукту: 1.03
Вот еще нарыл. Дешего и сердито. Плюс чтение/запис есть до кучи, с демками.