Re: Как получить серийные номера устройств в системе?
От: Alexey Frolov Беларусь  
Дата: 01.08.06 08:22
Оценка:
Здравствуйте, vanes, Вы писали:

V>2) Через непосредственно WINAPI. Но результатом было только GetLastError = ERROR_INVALID_FUNCTION (Incorrect function) после вызова функции DeviceIoControl. Вот главный кусок кода:


V>VOID EnumerateExistingDevices(const GUID* guid)

V>{
V> HDEVINFO info = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
V> SP_INTERFACE_DEVICE_DATA ifdata;
V> ifdata.cbSize = sizeof(ifdata);
V> DWORD devindex;
V> for (devindex = 0; SetupDiEnumDeviceInterfaces(info, NULL, guid, devindex, &ifdata); ++devindex)
V> {
V> DWORD needed;
V> SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &needed, NULL);
V> PSP_INTERFACE_DEVICE_DETAIL_DATA detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(needed);
V> detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
V> SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)};
V> SetupDiGetDeviceInterfaceDetail(info, &ifdata, detail, needed, NULL, &devdata);
V> CString devname = detail->DevicePath;
V> HANDLE hDevice = CreateFile (devname,
V> GENERIC_READ, // no access to the drive
V> FILE_SHARE_READ // share mode
V> ,
V> NULL, // default security attributes
V> OPEN_EXISTING, // disposition
V> 0, // file attributes
V> NULL); // do not copy file attributes

V> if(hDevice != INVALID_HANDLE_VALUE)

V> {
V> CHANGER_PRODUCT_DATA * product = new CHANGER_PRODUCT_DATA;
V> DWORD dwReturn = 0;
V> DWORD dwError = GetLastError();
V> OVERLAPPED aOverlapped;
V> BOOL bOk =DeviceIoControl ((HANDLE)hDevice, IOCTL_CHANGER_GET_PRODUCT_DATA, NULL, 0, product,
V> sizeof(CHANGER_PRODUCT_DATA), &dwReturn, &aOverlapped);
V> dwError = GetLastError();
V> if(bOk)
V> {
V> cout << "SerialNumber: " << product->SerialNumber << "n";
V> }
V> else
V> {
V> cout << "Error: " << GetLastError() << "n";
V> }
V> delete product;
V> CloseHandle(hDevice);
V> }

V> free((PVOID) detail);

V> }
V> }

V>Очень прошу при возможности привести РАБОТОСПОСОБНЫЙ код в ответе, если можно.


Насколько я понял вы делаете enumerate всех устройств, а запрос им отсылаете, как будто все они FILE_DEVICE_CHANGER. Так нельзя, это специфический запрос. Вам надо либо различать устройства и каждому посылать специфический запрос, либо попробовать вытащить serial number из Device Instance ID который можно получить с помощью функции
CM_Get_Device_ID(devdata.DevInst, strData, sizeof(data), 0);
Но не всегда там присутствует уникальный серийник, а только в том случае если железка имеет этот самый серийник, это можно проверить с помощью

            if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfoData, SPDRP_CAPABILITIES, &dwRegDataType, data, sizeof(data), &dwRequired))
            {
                DWORD capabilities = * ((DWORD *) data);
                devNode.UniqueSerialNumber = (capabilities & CM_DEVCAP_UNIQUEID) != 0;
            }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.