Getting USB HDD firmware serial no from CE.NET 4.2 device & x86 PC
Hopefully I haven't post this in the wrong place. If so, would someone be kind enough to point me to the correct site to post. Thanks in advance.
I am a developer working on a Windows project currently. The program I am working on runs on a Windows CE.NET 4.2 based embedded device with AMD Geode x86 embedded CPU. The device uses a removable IDE harddisk as storage. The hdd is packaged in such a way such that it can be removed and attached to a PC using a USB cable. I think it is USB 2.0. It will be recognized as a removable drive in the Windows explorer.
Right now, we need to enforce a licensing feature for our CE program such that the software can only be run in the HDD it is pre-installed in. That is done by reading the HDD firmware serial number (not filesystem volume serial number) and generate a unique key for this.
I have managed to get the serial number out using a CE.NET program and DeviceIoControl API with the IOCTL_DISK_GET_STORAGEID IO control code. However, I noticed that the serial number and the manufacturer's string obtained were flipped for every 2 bytes. E.g. (Note the serial number is a fake example)
Manufacturer ID: UFIJST UHM2T20A0 T
Serial Number: NNC76Z8576FG
The actual strings should be "FUJITSU MHT2020AT" and "NN7CZ65867GF". I have double checked this to be the case by physically opening the package and checked the serial number printed on the label of the drive.
The following is a segment of the code I have written:
HANDLE hDisk = CreateFile(_T("DSK1:"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (!hDisk)
return -1;
PSTORAGE_IDENTIFICATION pStoreInfo = (PSTORAGE_IDENTIFICATION) new BYTE[3000];
if (!pStoreInfo)
{
CloseHandle(hDisk);
return -1;
}
DWORD dwBytesRet;
if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_STORAGEID, NULL, 0, pStoreInfo, 3000, &dwBytesRet, NULL))
{
DWORD err = GetLastError();
delete [] pStoreInfo;
CloseHandle(hDisk);
return -1;
}
BYTE *ManuID = (((BYTE *)pStoreInfo) + pStoreInfo->dwManufactureIDOffset);
BYTE *SerialNo = (((BYTE *)pStoreInfo) + pStoreInfo->dwSerialNumOffset);
.......
For one, I could manually flip the bytes to get back the correct string, however, I was afraid that might cause compatibility problems with other platforms. I would need port this program onto the PC x86 platform for the license checking module.
Does anyone here knows what's the problem? Did I miss out something? Is the serial number of a USB hdd stored as UNICODE as mentioned in the "Universal Serial Bus Mass Storage Class Bulk-Only Transport" specifications? Does that affect my results or is it that I used the wrong IOCTL code?
============================================================
I have another related question.
(Note: In the previous case, the HDD is attached to the embedded device and recognized as a "storage device" on CE.NET)
I also need to work on the license checking module for this portion of the project. It would basically do the same thing as the one on the CE device. The HDD is attached to the PC using the USB cable. The PC program will read in the serial number using some APIs and perform a check on the license key generated.
I found that on the PC, I have to use other methods to read the number. I found a this program - diskid32 - at http://www.winsim.com/diskid32/diskid32.html. However, it only seems to work for fixed disk, not usb disk. I tried to modify the program to read USB drives but it failed.
I was thinking along the line of using SetupDixxxxx class of Win32 APIs to workaround it. But have yet to try it out.
Does anyone knows a good solution to this? I need to rush this project by the end of this month, hopefully earlier and your help will be greatly appreciated.
Thanks in advance,
Best Regards
Charles Wong

