15 November 2008

Read secure digital (SD) card serial number from the CID

(Quick link to an executable, this might read the serial number on Windows XP/Vista/32/64 when you are not using a USB card reader (so when you have the card in a slot on the side of a laptop it should work - though it depends on the driver!)). Requires .Net Framework 3.5.

I got an email about a post from ages ago on the msdn forums about reading the serial number from an SD Card. People want to do this as the number is factory stamped and unchangeable, so it could be used to protect programs from being copied. Distribute your program on an SD Card, have it check the serial, and have it fail if the number doesn't match a hard-coded version. Maybe there's more to it than that. But anyway the thread went along the lines of:

1) I want to read the serial 2) Someone suggested: Well use DeviceIOControl to send IOCTL_DISK_GET_STORAGEID to the drive.

At the time I'd just been playing with DeviceIOControl, and had spent ages working out how to use it from .Net. There weren't any useful examples that I could find. I was working at trying to make a CD Burner, using COM Interop to talk to IMAPI on XP (before IMAPI2). I'd learnt about DeviceIOControl, and how it can be used to send messages straight to a device. I used it to find out things that IMAPI couldn't tell you - like the exact media in the drive, and whether the drive was ready. I eventually got a vb.net program that could burn MP3s to CD. I never quite finished it though. I wasn't sure how to deal with all the possible errors during burning - there were so many!

I quickly wrote some code that demonstrated sending the message. I didn't know if the number was really the hardware stamped serial or whether it was just something windows dreamt up (like the volume serial you get with dir c:\).

I was asked again this week about this, and pointed in the direction of the concise SD specification (you can only see the big one if you pay $$$$, as it isn't an open standard). It's call the simplified version of the physical layer spec. This describes various commands that can be sent. Command 10 returns the CID. The CID is the bit we are interested in, the Card IDentification register:

Name Field Width CID-slice
Manufacturer ID MID 8 [127:120]
OEM/Application ID OID 16 [119:104]
Product Name PNM 40 [103:64]
Product Revision PRV 8 [63:56]
Product Serial Number PSN 32 [55:24]
reserved -- 4 [23:20]
Manufacturing Date MDT 12 [19:8]
CRC7 Checksum CRC 7 [7:1]
not used, always 1 -- 1 [0:0]

There we have 128 bits used to identify the device. I was asked if the number that my earlier program grabbed was this number from the CID. I don't know...(edit - NO it isn't the same. IOCTL_DISK_GET_STORAGEID is useless - it gets a serial that Windows invents when it formats a volume.)

I decided to try and get this CID number out, and I've managed to, but there are provisos. My program (VB.Net) currently works only on Vista 64. Weirdly it only works when compiled for the x86 platform (the build target in visual studio). When I tried it on Vista 32 I got invalid handle errors. Sheesh. The other biggy is that it only works when the SD Card is plugged into a reader that is attached directly to the pci bus. If USB is involved in the chain, then the DeviceIOControl messages go to the USB host controller, and it doesn't understand them. It works on my laptop's reader, but not on a fan controller/card reading gadget plugged in to my desktop as its card reader is attached via a USB header on the mobo.

Here are some pics of the CIDs. They came out reversed, and the endianness of the serial number and manufacturer date were unhelpful. In the pics below, the 16 bytes are the ones I got in my buffer, but reversed order. They tally quite well with the above table. But, the leftmost byte (0 in each case) shouldn't be there, and we are missing the CRC and final bit. So it goes - Unspecified byte, MID, OID, OID, PNM, PNM, PNM, PNM, PNM, PRV, PSN, reserved+MDT, MDT. And the CRC is missing.

CIDS

I bought the two Crucial 4GB cards at the same time, note the serial numbers are adrift by 2 - a good indication I'm not getting gobbledegook. The Manufacture date is mm/yyyy. Also the numbers tally with the hardware IDs found in Windows Device Manager, which are described in the DDK, er WDK rather. Which you can get for free now. I bought the Veho card two weeks ago, looks like it was made just last month. It also looks like Vehos are made by Corsair - or maybe they are both made by some other company. Crucial don't fill in the product name or version, all the bytes were 0.

The bit where is says "This is an SD card", is because it also checks if the drive selected in the combobox is an SD card before attempting to get data.

So, how's it done? Well, you send an IOCTL specifying an SD Command with DeviceIOControl. Again it's in the WDK. These are just user mode calls, so we aren't in the realms of writing a driver. The main difficulties were trying to decipher the documentation, which appears to be plain wrong in places. This lead to many many errors being returned by DeviceIOControl. Eventually I managed to send off command 0 without any complaint whatsoever, and figured I must be doing something right. I was using C++ code from elsewhere in the msdn forums and a bit of C++ Interop. I then got something back from cmd 10. I then went and did it in VB.Net instead as all this C++ was driving me mad. I can read it, but programming in it is a very laborious process for me.

I used IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL to check if a mount point was an SD card. Then IOCTL_SFFDISK_DEVICE_COMMAND to send cmd10. DeviceIOControl just takes the IOCTL code and a blob of memory - in .Net I used a byte array. The byte array contains a SFFDISK_DEVICE_COMMAND_DATA structure first, then the SDCMD_DESCRIPTOR. Both of these structures were 20 bytes big on x64 vista when using c++, so I made sure they were that size in .Net too. The Cmd field of SDCMD_DESCRIPTOR is very nasty. The documentation says to fill it with a value from the SD_COMMAND_CODE data type and lists two "allowed values". Well, both of those values give errors. Instead you should set the sd command code - i.e. 10 for command 10, 0 for command 0!!!!! After that structure I sent 16 bytes to receive the CID. And unfortunately I get 15 bytes of CID with a 00 in front and no CRC. Maybe I have some alignment problems with the structures. It might explain why my code isn't porting too.

I'll iron out the bugs and try and get it running on my dilapidated axim 50v too with the compact framework. I'm currently attempting to flash the rom on it to something newer. I nearly binned it last week in a grand tidy up. I'll have to download the academic version of Visual Studio, which is Pro, to do the windows mobile stuff. I've only got Standard (which was a MS freebie from the launch). Code to follow. (note there are other, newer, posts on this on the blog, and some other code)

47 comments:

  1. you are Life saver.....

    ReplyDelete
  2. Hi!
    How to works ReadCID.exe?
    I have Windows 7 Ultimate. ReadCID is compatible with them?
    The program is display only one console window for me.

    ReplyDelete
  3. I`v got the same problem - WinXP SP3.

    ???

    ReplyDelete
  4. I try on 3 computers, with inside reader. Always the same:

    Console window and nothing more.

    What to do ?

    ReplyDelete
  5. Where do you download the Microsoft driver for the reader, I seem to have the same problem for the driver so I would like to try to change the driver for the Ricoh reader..

    Thanks

    ReplyDelete
  6. I was looking for this function too but could never get a home brewed solution. I ended up finding a company that makes an SID reader. Go to nexcopy.com and look in their SD or microSD duplicator section. It can do 20 cards at a time

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Copyright © MyBum 2008 LOL

    Now, seriously find a way to read it using a normal card reader.
    Perhaps using scsi?
    Pass-thru?

    ReplyDelete
  9. Shameless commercial plug from Jesus
    Jesus Velazquez – Production Manager
    Jesus joined Nexcopy in 2010 as a production supervisor for Nexcopy. Jesus now oversees all manufacturing and quality control for Nexcopy and manages the shipping and receiving department.

    ReplyDelete
  10. Has the exe moved? It says "this item won't load right now."

    ReplyDelete
  11. cant find download link for READCID.. ?? would appreciate link..
    thanks

    ReplyDelete
  12. I develop software for SAS regarding SD card CID serial numbers. When all other attempts fail, message me at harrisonking1883 AT gmail.com

    ReplyDelete
  13. What will be the value for physicaldrive, if it is set to \\\\.\\PHYSICALDRIVE1 then the IsInvalid pointer gets set to true so I'm not able to move ahead. If i set it to the path of drive \\\\.\\G: then the result value in IsSD function turns out to be false & queryData object of type SffdiskQueryDeviceProtocolData holds the value 000000...... for the value of protocol GUID. Please help I am working on this since past few days. I tried this on Windows 7 & 8.1

    ReplyDelete
  14. Hi,

    I was writing program in C++ to read CID register. The procedure I have followed is almost same but I am also facing the same issue .." I get 15 bytes of CID with a 00 in front and no CRC."
    Were you able to root cause the reason for the same. Even when reading the whole buffer, this value is not there itself.

    Regards,
    Rakendra

    ReplyDelete
  15. Hi there, I extracted the files to my desktop. After clicking on it, there is only a blank black screen cmd that came out and nothing happens.

    I am using Windows 8.1.

    May u advice pls? Thank you.

    ReplyDelete
    Replies
    1. same problem with me on windows 7. i even tried running it on compatibility mode using windows vista and XP. BUT NOTHING :(

      Delete
    2. hi sir

      shall you send me the source on jitu93.ecer@gmail.com

      Delete
  16. Where is the link to the executable fie?

    ReplyDelete

  17. Nice Article, Keep it up!
    Get Daily Tech News, Guides Softwares & Tips & Tricks => Google Gangs

    ReplyDelete
  18. Good Job, I really appreciate your effort. Keep it up Bro!
    Get Daily Latest Tech News , Guides , Best PC Softwares & Tips & Tricks => How to fix corrupted sd card

    ReplyDelete
  19. You made such an interesting piece to read, giving every subject enlightenment for us to gain knowledge. Thanks for sharing the such information with us to read this... Read about free psn codes

    ReplyDelete
  20. Banking as a service
    Traditionally, services have solved specific functional needs; food for example, was a process of purchase and preparation at the very least, or going out to eat, involving distance, time, travel and expense.

    ReplyDelete
  21. That is really attention-grabbing, You are a very skilled blogger. I’ve joined your rss feed and look forward to searching for more of your fantastic post. Also, I have shared your website in my social networks

    야한동영상
    오피
    외국인출장
    마사지

    ReplyDelete
  22. I’ve seen articles on these topics a few times, but I think your writing is the cleanest I’ve ever seen. I would like to refer to your article on my blog and write it.
    토토사이트
    경마사이트
    경마

    ReplyDelete
  23. I was actually captured with the piece of resources you have got here. Big thumbs up for making such wonderful blog page!
    카지노
    사설토토

    ReplyDelete
  24. i am glad to discover this page : i have to thank you for the time i spent on this especially great reading !! 토토사이트

    ReplyDelete
  25. This could be a problem with my internet browser because I’ve had this happen before. Thank you

    무료야설
    휴게텔
    마사지
    출장마사지
    온라인카지노

    ReplyDelete
  26. Thank you for sharing this information. I read your blog and I can't stop my self to read your full blog. 카지노

    ReplyDelete
  27. Excellent write-up. I absolutely appreciate this website. 토토사이트

    ReplyDelete
  28. Thanks for the update and quick reply. I’ll be sure to keep an eye on this thread. 온라인경마

    ReplyDelete
  29. Never knew this, regards for letting me know. 스포츠토토

    ReplyDelete
  30. Great blog! Do you have any tips for aspiring writers? I’m hoping to start my own blog soon but I’m a little lost on everything. 블랙잭사이트

    ReplyDelete
  31. I have got much clear idea regarding from this article.I am pleased that I observed this site . 바카라사이트

    ReplyDelete
  32. Way cool! Some very valid points! I appreciate you writing this
    write-up and also the rest of the site is very good.


    https://www.totosafeguide.com

    ReplyDelete
  33. I really really love it. It's so good and so awesome. I am just amazed. 토토사이트링크

    ReplyDelete
  34. What’s up, after reading this remarkable paragraph i am as well delighted to share my know-how here with mates.카지노사이트

    ReplyDelete
  35. This blog is really helpful for the public .easily understand,
    Thanks for published,hoping to see more high quality article like this.
    온라인카지노

    ReplyDelete
  36. Thanks for taking the time to discuss this,

    ReplyDelete
  37. It is great to visit your website.

    ReplyDelete