Текущий архив: 2007.07.15;
Скачать: CL | DM;
Вниз
как можно узнать модель USB-устройства? Найти похожие ветки
← →
Ral'f (2007-06-14 14:47) [0]Серийный номер 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 устройств там, правда, есть!
Но тогда как связать в программе - запись в реестре и букву диска?
Теперь вопрос даже - как вообще можно идентифицировать внешнее устройство (будь это флешка, плекстор или карта памяти)?
← →
Dimaxx © (2007-06-15 14:28) [4]Вот тебе в помощь. Как раз определяется и тип устройства, и модель, и серийный номер.
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.
← →
Dimaxx © (2007-06-15 14:31) [5]Да, забыл отметить. USB-накопители (флэшки, USB-винты) в системе становятся съемными жесткими дисками, поэтому к ним можно обращаться через CreateFile, следовательно, вышеуказанные примеры к ним применимы.
← →
Ral'f (2007-06-15 15:32) [6]> IdeInfo2 - получение различной информации об IDE диске
- то, что нужно, НО в XP не работает (а сейчас в основном везде эта ОС)
> IdeSN2 - получение серийного номера первого IDE диска
- в первом, как раз, у меня необходимости то и нету!
← →
Ral'f (2007-06-15 15:33) [7]Всё-равно спасибо!
← →
Dimaxx © (2007-06-15 16:18) [8]У меня все работает под ХР. Недавно проверял и брал оттуда некоторые вещи для своей проги.
← →
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 !
← →
Dimaxx © (2007-06-15 21:59) [10]Я же написал, что все флэш накопители становятся съемными жесткими дисками. Значит обращаться к ним надо не
CreateFile(PChar("\\.\С:")
, а как к физическому устройству, т.е.CreateFile(PChar("\\.\PhysicalDriveХ")
, где Х - номер фичиеского устройства.
← →
Dimaxx © (2007-06-15 21:59) [11]Я же написал, что все флэш накопители становятся съемными жесткими дисками. Значит обращаться к ним надо не
CreateFile(PChar("\\.\С:")
, а как к физическому устройству, т.е.CreateFile(PChar("\\.\PhysicalDriveХ")
, где Х - номер физического устройства.
← →
Ral'f (2007-06-16 08:54) [12]> к ним надо не CreateFile(PChar("\\.\С:"), а как к физическому устройству
Думаешь я не пробовал?!!!!!!!
← →
koha © (2007-06-16 12:39) [13]
> Ral"f (14.06.07 14:47) [0]
Найди книгу "Интерфейс USB практика использования и программирования"
Автор: Павел Агуров. Издатель: Санкт-Петербург "БХВ-Петербург" 2005
- там почти все про USB
← →
Ral'f (2007-06-16 12:56) [14]Так и придётся сделать! Надеялся по-быстренькому... :-)))
Пока я, наверно, буду использовать метку тома, а там глядишь - мож что вычитаю!
Правда, пока искал неоднократно встречал сообщения про NoName устройства, вроде как от серийников во всём мире сейчас отказываются. Так что, может, и связываться не стоит!
← →
Riply © (2007-06-16 20:21) [15]Искомое можно получить, примерно, так:
Весь код не привожу, т.к. его очень сложно выдернуть из проекта.
Опишу, только, подводные камни, с которыми я столкнулась
Первая проблема: несоответствие размера параметров структур из заголовочных файлов С++ с Delphi.
Здесь мой вариант ее решения(не факт, что правильный, но рабочий :)
Менять закоментированность {$MINENUMSIZE 4} не рекомендуется :)
Я предпочла не везде его({$MINENUMSIZE) использовать,
а ввести доп. поле _Fill: array[0..2] of Byte; в _STORAGE_DEVICE_DESCRIPTOR
и изменить размерность AdditionalParameters: array[0..9] of Byte в STORAGE_PROPERTY_QUERY
т.к. было необходимо поддержать "совместимость размерности» и в др. запросах и структурах.
type
//{$MINENUMSIZE 4}
PSTORAGE_QUERY_TYPE = ^STORAGE_QUERY_TYPE;
_STORAGE_QUERY_TYPE = (PropertyStandardQuery = 0, // Retrieves the descriptor
PropertyExistsQuery, // Used to test whether the descriptor is supported
PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor
PropertyQueryMaxDefined); // use to validate the value
STORAGE_QUERY_TYPE = _STORAGE_QUERY_TYPE;
//{$MINENUMSIZE 4-}
type
//{$MINENUMSIZE 4}
PSTORAGE_PROPERTY_ID = ^STORAGE_PROPERTY_ID;
_STORAGE_PROPERTY_ID = (StorageDeviceProperty = 0, StorageAdapterProperty, StorageDeviceIdProperty);
STORAGE_PROPERTY_ID = _STORAGE_PROPERTY_ID;
//{$MINENUMSIZE 4-}
type
PSTORAGE_PROPERTY_QUERY = ^STORAGE_PROPERTY_QUERY;
_STORAGE_PROPERTY_QUERY = packed record
PropertyId: STORAGE_PROPERTY_ID;
QueryType: STORAGE_QUERY_TYPE;
AdditionalParameters: array[0..9] of Byte;
end;
STORAGE_PROPERTY_QUERY = _STORAGE_PROPERTY_QUERY;
type
{$MINENUMSIZE 4}
PSTORAGE_BUS_TYPE = ^STORAGE_BUS_TYPE;
_STORAGE_BUS_TYPE = (BusTypeUnknown = 0, BusTypeScsi, BusTypeAtapi, BusTypeAta, BusType1394,
BusTypeSsa, BusTypeFibre, BusTypeUsb, BusTypeRAID, BusTypeiScsi,
BusTypeSas, BusTypeSata, BusTypeMaxReserved = $7F);
STORAGE_BUS_TYPE = _STORAGE_BUS_TYPE;
{$MINENUMSIZE 4-}
type
PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR;
_STORAGE_DEVICE_DESCRIPTOR = packed record
Version: DWord; // Sizeof(_STORAGE_DEVICE_DESCRIPTOR)
Size: DWord; // Total size of the descriptor, including the space for additional data and id strings
DeviceType: Byte; // The SCSI-2 device type
DeviceTypeModifier: Byte; // The SCSI-2 device type modifier, if any, - this may be zero
RemovableMedia: Boolean;
CommandQueueing: Boolean;
VendorIdOffset: DWord;
ProductIdOffset: DWord;
ProductRevisionOffset: DWord;
SerialNumberOffset: DWord;
BusType: STORAGE_BUS_TYPE;
RawPropertiesLength: DWord;
_Fill: array[0..2] of Byte;
RawDeviceProperties: array[0..0] of Byte;
end;
STORAGE_DEVICE_DESCRIPTOR = _STORAGE_DEVICE_DESCRIPTOR;
Разобравшись с размерами полей, переходим к попытке получить, нужные нам данные:
Следующий сюрприз: при нашем запросе, если мы задали слишком маленький буффер для приема данных,
мало того, что этот поросенок (DeviceIoControl :) вернет True, так еще и
GetLastError вернет нам ERROR_SUCCESS :)
В нашем запросе значения ERROR_MORE_DATA и ERROR_INSUFFICIENT_BUFFER,
GetLastError, почему-то выдавать не хочет :)
Схема того, как я пыталась бороться c этим "все в порядке" ниже.
const
IOCTL_STORAGE_QUERY_PROPERTY = ((IOCTL_STORAGE_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
($0500 shl 2) or 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_QUERY), 0);
PropQuery.PropertyId := StorageDeviceProperty;
PropQuery.QueryType := PropertyStandardQuery;
while DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
@PropQuery, SizeOf(STORAGE_PROPERTY_QUERY),
pDescript, cbDescript, cbReturned, nil) do
begin
Result := GetLastError;
case Result of
ERROR_SUCCESS:
if (pDescript.Size >= cbReturned) then
begin
cbDescript := pDescript.Size + DEVICE_DESCRIPTOR_INC;
ReallocMem(pDescript, cbDescript);
end
else Break;
// ERROR_MORE_DATA:
// begin
// if 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
ProductRevision: 1.03
← →
Riply © (2007-06-16 20:29) [16]> [15] Riply © (16.06.07 20:21)
Забыла добавить к
"Следующий сюрприз: при нашем запросе, если мы задали слишком маленький буффер для приема данных,
мало того, что этот поросенок (DeviceIoControl :) вернет True, так еще и
GetLastError вернет нам ERROR_SUCCESS :)"
cbReturned вернет сколько байт реально записано, а не сколько на самом деле нужно.
← →
Dimaxx © (2007-06-18 10:43) [17]Вот еще нарыл. Дешего и сердито. Плюс чтение/запись есть до кучи, с демками.
http://www.soft-gems.net/supplement/download.php?ID=37
Страницы: 1 вся ветка
Текущий архив: 2007.07.15;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.038 c