Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.05.2011, 23:53   #1
Dee63
Пользователь
 
Аватар для Dee63
 
Регистрация: 09.03.2010
Сообщений: 48
По умолчанию Получение серийника USB

Всем привет!
Задача- прочитать серийник флешки ( а вместе с тем и вендора и пр лабуду).

Делаю так:

Код:
uses
 JwaWinIoctl;
function GetFlashSN:String;
var
    Dummy :DWord;
    FHandle :Cardinal; 
    RealPath :String; 
    dg :CHANGER_PRODUCT_DATA;
    Serial,venid,prodid,rev,devtype :String;
    i :byte;
begin
 RealPath:=string(form1.Edit1.text);
//открываем файл (из эдита получаем. использую \\.\G:)
 FHandle:=CreateFile(PChar(RealPath),GENERIC_READ,FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  
Memo1.lines.add('Сообщение CreateFile для '+realpath+' - '+#13+' '+SysErrorMessage(GetLastError)+#13+' '+Inttostr(GetLastError));
  
if  (DeviceIOControl(FHandle,IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, nil, 0, @dg, sizeof(dg), dummy, nil)) then
begin
Serial:='';
venid:='';
prodid:='';
rev:='';
devtype:='';
for i:=0 to 7 do
venid:=venid+'-'+inttostr(dg.VendorId[i]);
for i:=0 to 15 do
prodid:=prodid+'-'+inttostr(dg.ProductId[i]);
for i:=0 to 3 do
rev:=rev+'-'+inttostr(dg.Revision[i]);
for i:=0 to 31 do
Serial:=Serial+'-'+IntToStr(dg.SerialNumber[i]);
      
devtype:=inttostr(dg.devicetype);
end;
  form1.memo1.lines.add('Vendor ID: '+venid);
  form1.memo1.lines.add('Product ID: '+prodid);
  form1.memo1.lines.add('Revision ID: '+rev);
  form1.memo1.lines.add('S\N: '+serial);
  form1.memo1.lines.add('Device Type: '+devType);
end;
Что получаю в итоге.
Вообще результата было 2:
1- первые пол часа проверки с 10 флешками- номера выдавалаись полностью уникальными, и начинались на 0370 и т.д.
2-вторые пол часа проверки (повторный запуск ТОГО ЖЕ кода) стали давать другие номера, и начинались с 0136 и т.д.

И третье-не результат, а просто пустота.

Вопрос-что я не так делаю?
По коду-открытие файла происходит без проблем (о чем свидетельствуетвывод инфы о действии).
А номера вот никакие не приходят ко мне в dg (именно в него и должно приходить все ето безобразие).

Помогите люди добрые-ткните пальцем где косяк

Последний раз редактировалось rpy3uH; 04.05.2011 в 10:10.
Dee63 вне форума Ответить с цитированием
Старый 04.05.2011, 10:23   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

я тоже занимался этой проблемой, но так и не добился результатов. получал серийные номера и ID через SetupAPI. Я смог получить почти все значения и выпадающего списка но "Код экземпляра устройства никак не получается"
Вот функция которая их получает.

Выделенные строки на скриншотах уникальны для каждой флешки. Они разные даже для двух одинаковых флешек.
Сравнивай значения полученные твоей программой с этими если они совпадают, значит твоя программа работает нормально.

Каждая флешка в системе представлена как несколько устройств: как дисковый накопитель и как устройство USB. Их коды немного отличаются он цифры в них идентичные, просто добавляются некоторые буковки.

Изображения
Тип файла: jpg flash_UID_dd.JPG (80.9 Кб, 492 просмотров)
Тип файла: jpg flash_UID.JPG (87.4 Кб, 461 просмотров)

Последний раз редактировалось rpy3uH; 04.05.2011 в 10:27.
rpy3uH вне форума Ответить с цитированием
Старый 04.05.2011, 10:42   #3
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Максимум что у меня получалось : это получить уникальные коды флешек во время из вставки и выдёргивания. В воткнутом состоянии никак, в основном ерунду получаю.

В своей статье я писал как узнать когда вставляют новое устройство

В прицепе программа-пример к этой статье. На скришоте показано где выводятся уникальные коды флешек. Они составляются из кода экземпляра плюс какой-то GUID. в общем смысл понятен, если что-то получиться сделать отпишись пожалуйста
Изображения
Тип файла: jpg flash_UID_2.JPG (82.1 Кб, 185 просмотров)
Вложения
Тип файла: zip DeviceWork.zip (248.6 Кб, 122 просмотров)
rpy3uH вне форума Ответить с цитированием
Старый 04.05.2011, 11:46   #4
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

тырк 1 2 3
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 04.05.2011, 16:57   #5
Dee63
Пользователь
 
Аватар для Dee63
 
Регистрация: 09.03.2010
Сообщений: 48
По умолчанию

грузин, СПАСИБО!

Подкинул идеи.
Буду ковырять дальше вопрос.
Конечно исходники твои еще править и править, но в целом очень помогло.
Dee63 вне форума Ответить с цитированием
Старый 06.05.2011, 11:54   #6
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

В целом, согласно спецификаций заложенных в USB, серийник не является обязательным для USB устройств, и реализация серийника в прошивке оставленна на усмотрение производителя. В случае если производитель решает использовать серийные номера он должен обеспечить их уникальность. Это я к тому, что в большинстве никто не утруждает себя написанием мега прошивок с поддержкой опциональных USB фичей.
Винда в свою очередь для собственного удобства генерит уникальные идентификаторы, которые являются именами ключей в реестре (HKLM\System\CurrentControlSet\Enum \USB\Vid&Pid\имя). В целом эти ключи единсвенные к которым может получить доступ драйвер устройства, для сохрания кофигурации или данных.
Если у устройства и есть некий уникальный ID, то он скорее всего всего нацарапан лазером на корпусе.
Ну а для чтения USB дескрипторов можно пользоваться DeviceIoControl с IOCTL_GET_USB_DESCRIPTOR.
f.hump вне форума Ответить с цитированием
Старый 07.05.2011, 16:11   #7
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Просмотрел свой код, IOCTL_GET_USB_DESCRIPTOR работате только для imaging device.
Немного покурил, получилась вот такая фигня:
Код:
#include <Windows.h>
#include <setupapi.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <devguid.h>
#include <cfgmgr32.h>


#define BUFFER_SIZE 1024

struct stUSBStorDesc {
	wchar_t * manufacturer, * product, * revision, * pid, * vid, * serial;
};

int main()
{
	int result(0);
	HDEVINFO hwInfo(0);
	unsigned int i(0);
	DWORD bcount(0);
	stUSBStorDesc devDesc;
	DEVINST dInst(0);
		
	
	hwInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE,0,0,DIGCF_PRESENT);
	
	if (hwInfo != INVALID_HANDLE_VALUE) {
		i = 0;
		SP_DEVINFO_DATA devInfo;
		wchar_t instanceIDString[2*BUFFER_SIZE], * tempStrA(0), * tempStrB(0);
		
		devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
		for (;;) {
			if (SetupDiEnumDeviceInfo(hwInfo,i,&devInfo)) {
				tempStrA = instanceIDString; tempStrB = instanceIDString+BUFFER_SIZE;

				if (CR_SUCCESS == CM_Get_Device_ID(devInfo.DevInst,tempStrA,BUFFER_SIZE,0)) {
					if (wcsstr(tempStrA,L"USBSTOR")) {
						if (CR_SUCCESS == CM_Get_Parent(&dInst,devInfo.DevInst,0)) {
							if (CR_SUCCESS == CM_Get_Device_ID(dInst,tempStrB,BUFFER_SIZE,0)) {
								devDesc.vid = wcsstr(tempStrB,L"VID_");
								if (devDesc.vid) {
									devDesc.vid[8] = L'\0';
									tempStrB = devDesc.vid + 9;
									devDesc.vid += 4;
								}

								devDesc.pid = wcsstr(tempStrB,L"PID_");
								if (devDesc.pid) {
									devDesc.pid[8] = L'\0';
									tempStrB = devDesc.pid + 9;
									devDesc.pid += 4;
								}

								devDesc.serial = tempStrB;


							}

						}

						devDesc.manufacturer = wcsstr(tempStrA,L"VEN_");
						devDesc.product = wcsstr(tempStrA,L"&PROD_");
						devDesc.revision = wcsstr(tempStrA,L"&REV_");

						tempStrB = 0;
						if (devDesc.manufacturer) {
							devDesc.manufacturer += 4;
							tempStrB = devDesc.manufacturer;
						}
						if (devDesc.product) {
							devDesc.product[0] = L'\0';
							devDesc.product += 6;
							tempStrB = devDesc.product;
						}
						if (devDesc.revision) {
							devDesc.revision[0] = L'\0';
							devDesc.revision += 5;
							tempStrB = devDesc.revision;
						}

						if (tempStrB) {
							tempStrA = wcsstr(tempStrB,L"\\");
							if (tempStrA) tempStrA[0] = L'\0';
						}
						
						
						wprintf(L"\n=====================================================================%04d=====\n",i);
						if (devDesc.manufacturer) wprintf(L"\n  Manufacturer: %s",devDesc.manufacturer);
						if (devDesc.vid) wprintf(L"	VID: %s",devDesc.vid);
						if (devDesc.product) wprintf(L"\n  Product: %s",devDesc.product);
						if (devDesc.pid) wprintf(L"	PID: %s",devDesc.pid);
						if (devDesc.revision) wprintf(L"\n  Revision: %s",devDesc.revision);
						if (devDesc.serial) wprintf(L"	S/N: %s",devDesc.serial);
						
						wprintf(L"\n");

					}

				}


				i++;
				if (GetLastError()) continue;	



			} else {
				result = GetLastError();
				if (result == ERROR_NO_MORE_ITEMS) result = 0;
				break;

			}
		}


		SetupDiDestroyDeviceInfoList(hwInfo);
	}

	_getch();
	return result;
}
Надеюсь поможет.

Последний раз редактировалось f.hump; 07.05.2011 в 18:42. Причина: покурил еще немного
f.hump вне форума Ответить с цитированием
Старый 08.05.2011, 13:24   #8
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Прочитал наконец-то код из первого поста.
Для того чтобы получить CHANGER_PRODUCT_DATA нужно спрашивать IOCTL_CHANGER_GET_PRODUCT_DATA.
Результат - ASCII строки, конвертировать их inttostr не нужно (кроме DeviceType котрый всегда должен быть равен MEDIUM_CHANGER).
f.hump вне форума Ответить с цитированием
Старый 25.05.2011, 11:48   #9
Dee63
Пользователь
 
Аватар для Dee63
 
Регистрация: 09.03.2010
Сообщений: 48
По умолчанию

f.hump, спасибо за участие.

2 all
решил проще-через wmi запрос.
Винда все выдает в виде строки. А дальше парсим ее и выдераем что нужно.
Dee63 вне форума Ответить с цитированием
Старый 03.04.2012, 17:55   #10
exploit.vn
Новичок
Джуниор
 
Регистрация: 03.04.2012
Сообщений: 1
Радость

Цитата:
Сообщение от Dee63 Посмотреть сообщение
f.hump, спасибо за участие.

2 all
решил проще-через wmi запрос.
Винда все выдает в виде строки. А дальше парсим ее и выдераем что нужно.
Добрый день.
А можно пожалуйста, по-подробнее, какой именно wmi-запрос выполнять, а то там просто гора инфы.
exploit.vn вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
3G usb-модем и получение смс belarusfight C/C++ Сетевое программирование 4 22.01.2012 21:53
USB BNTU Помощь студентам 4 22.04.2011 01:31
QT4 - Определение серийника жёсткого диска xwicked Qt и кроссплатформенное программирование С/С++ 2 06.08.2010 23:35
mini USB на USB viks1 Компьютерное железо 5 07.12.2009 23:31
C pc\2 на USB RockForr Компьютерное железо 12 22.09.2009 19:43