The missing TagAttribute in DotNet Framework

Wednesday, 27 February 2008 18:17 by Alan Mojab

For one strange reason I adore the Tag property. The Tag property has been around for as long as I remember.

I love practical things, so much so, I’d get so excited about them regardless how cheap or small they are. The Tag property is one of them. It always comes to your rescue and it never let you down.

The Attribute class in .Net Framework plays an important role and the developers can take advantage of this class to extend it for their own use. The extended attribute class normally is used for storing some kind of meta-data for types.

Imagine what you could have done if from day one or at least from Framework 1.1 Microsoft introduced a TagAttribute that looked something like the snippet below:

Quite often I could have solved design issues if the TagAttribute was part of the .Net framework itself rather than to distribute the extended version with my code. If you have noticed almost all protection tools would distribute one such attribute class so that you can mark a class to be ignored or to be processed.

The community that is driven by collecting virtual points

Friday, 22 February 2008 20:32 by Alan Mojab

Earlier today I submitted an insufficient article to CodeProject site (guilty as charged) that was deleted. To post the article I had to spend time to register first and then go through the article wizard to submit it.

I was then promptly emailed by the web master notifying me about my article removal. I accepted their decisions gracefully and replied back thanking them for notifying me.

Since I didn’t want to duplicate the article else where (my article, my call) I just left a brief summary (Introduction) and the link to my blog. I also apologized for redirecting the users to my blog instead. Submitting the hard drive serial number post to my blog was hard enough let alone I wanted to go through the whole process of reformatting everything again.

Seconds before my article was removed I visited my article’s page to see if there were any comments that I needed to reply. I was shocked by what I have discovered. I couldn’t believe I became a victim of CodeProject users myself.

None of the comments apart from one that I’ll explain were directly related to the subject of my article. Virtually every single user tried to hammer me for being lazy with my article and talking about ‘votes’ and what I should have done to increase my chances for collecting their votes, huh? I didn’t know CodeProject had gathered the best brains in I.T. community.

They don’t know it yet but they all have actually voted for me but for being lazy. I must have been on a bottle of JD or two while I was looking for a solution on google. This is totally out of character for a lazy person, don’t you say?

I have to admit I’m really confused right now because either me is trapped in another world or they are and if they are I know what world that is, virtual. Incidentally one of the users were MVP (allegedly) that replied in a fashion that only himself could read it, or was he on JD too? I’m sure he was rich and loaded with virtual points.

The other user commented something along “nothing new anyway”. His reply was almost at the bottom of someone else’s reply thread. Sorry mate! I must have missed your article on the same subject among the 55,000,000 hits I got when I searched for “hard drive serial number” on google the other day.

To train a new gang member (normally a kid who is hanging around more senior gang members) they would pick a victim and bash him until he is defenceless then ask the kid to have a go at the victim. Some how when I read his reply it reminded me of the gang movies I watched on the telly.

I’m sure I’ve been a visitor of the CodeProject site longer than the registered users who replied to my article so rudely. I’ve seen the same thing many times on CodeProject site where a developer’s article was picked on by the same type of users. In some cases they were really rude to the author that I felt so sorry for the chap. I hold CodeProject responsible for not kicking out such users.

Obviously I would never try to contribute to a community that encourages its users to collect virtual points and doesn’t screen its site properly again. I’ve been around long enough to know this kind of system is open to abuse.

The true lazy developers just submit questions to such community sites so that others rush to answer them first to pick up the points, then what?

I’ll blog about the side effect of the Developer Communities in the near future.

I’d like personally to thank the bad wolves because you would make the good guys look apart.

As I was about to submit this post I received an email that was automatically sent to me via www.asp.net when someone replies to my thread. My thread on asp.net’s forum was the same as CodeProject’s but see the difference for yourselves at http://forums.asp.net/t/1223845.aspx.
Tags:  
Categories:   General
Actions:   E-mail | del.icio.us | Kick it! | DZone it! | Permalink | Comments (0) | Comment RSSRSS comment feed

The trick to get the real serial number of hard drive

Friday, 22 February 2008 12:14 by Alan Mojab

Here is the solution that would save you hours of research without a success. I have already turned every page on google (literally but spent over 50 hours before I discovered my solution) without a success so you are in the right place right now.

There are two solutions to this so you can pick the one that fits your needs best. Both solutions works under user account on XP and Vista. Without google I wouldn’t know anything about windows registry forensic techniques that helped to find these solutions.

Solution 1: Getting the serial number from Windows Registry

The serial numbers are stored under the following path:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\IDE

Or

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\SCSI

This solution is much harder to dig out the serial number as it needs searching child keys and parsing strings.

The child nodes that are listed under the above keys can contain CDROM drives as well or any device has been categorised as IDE/SCSI but you can examine a Key value called ‘Class’ to see if the drive is ‘CDROM’ or  ‘DiskDrive’. Expand the child nodes until you find the Key called ‘Class’ in the left pane of Windows Registry.

On my machine I have two hard drives… In case you never thought about this every machine that is designed to be a development machine must have two hard drives. One is used by OS and other Programs and the second one for your data/source code. You would reduce the risk of losing your source code tremendously by this setup.

Here is one of key entries for one of my hard drives:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\IDE\

DiskMaxtor_6V160E0__________________________VA111630

Model Number: DiskMaxtor_6V160E0 (The word ‘Disk’ is a prefix that is added by PnP service)

Controller Revision Number: VA111630

You should be able to see another child node below the above key. Here is mine:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\IDE\

DiskMaxtor_6V160E0__________________________VA111630\
3356333038524743202020202020202020202020

The child node 3356333038524743202020202020202020202020 is your serial number in hexadecimal. At the time I had no idea what that number was until I used Smarties2008’s Hex tool to examine the value. I can assure you if it wasn’t for the Hex tool in Smarties 2008 not in a million year I would have guessed the number I was looking at was actually my hard drive serial number.

However, there is one more thing you need to know. Once you converted the Hex value to string then you need to reverse every two characters to get the serial number in the correct order, if that was needed.

Notes:

If there is no serial number returned by the Hard Drive the PnP service would generate a serial number for the Hard Drive. You might notice the ‘&0’ characters in the serial number. Depending where they appear they mean something but I don’t know what they mean as I have decided not to use the Windows Registry solution all together. The second solution is much easier.

If you decided to use this solution then make sure you always open a key for ‘read’ that way you never face security permission issue under user account privilege.

Solution 2: Getting the serial number from WMI

Here how is done in my way that works under User Account both on XP and Vista:


ManagementScope managementScope = new ManagementScope(@"\root\cimv2"); 
managementScope.Options.Impersonation = system.Management.ImpersonationLevel.Impersonate; 
ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, new ObjectQuery("SELECT * FROM Win32_DiskDrive WHERE InterfaceType=\"IDE\" or InterfaceType=\"SCSI\"")); 
foreach (ManagementObject disk in searcher.Get()) 
{ 
    if (disk["PNPDeviceID"] != null) 
    { 
       string pnpDeviceID = disk["PNPDeviceID"].ToString(); 
       string[] split = pnpDeviceID.Split('\\'); 
    } 
}

The serial numbers have been hidden in PNPDeviceID property of Win32_DiskDrive class all this time and if someone knew about it he/she never gave away the secret, not even the ‘Scripting Guy’ shared the secret with us.

Here is the value of PNPDeviceID property from the same hard drive that I used in Windows Registry example:

IDE\DISKMAXTOR_6V160E0__________________________VA111630\
3356333038524743202020202020202020202020

It looks familiar doesn’t it? Now you can split this string by ‘\’ character to get the serial number in the last element of the split. Once again the 3356333038524743202020202020202020202020 value needs to be converted from Hex to string then reverse every two characters to get the serial number in the right order.

Here is a quick dirty way to reverse it:

private string ReverseSerialNumber(string serialNumber) 
{ 
    serialNumber = serialNumber.Trim(); 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < serialNumber.Length; i += 2) 
    { 
        sb.Append(serialNumber[i + 1].ToString() + serialNumber[i].ToString()); 
    } 
    serialNumber = sb.ToString(); 
    sb = null; 
    return serialNumber; 
}/[code] 


And here is the code to convert Hex to String 


[code=csharp]private static Byte[] GetHexStringBytes(string hex) 
{ 
    try 
    { 
        if (hex.Contains(String.Empty)) 
        { 
            hex = hex.Replace(" ", String.Empty); 
        } 
        if (hex.Length % 2 == 1) 
        { 
            hex = "0" + hex; 
        } 
        int size = hex.Length / 2; 
        Byte[] bytes = new Byte[size]; 
        for (int i = 0; i < size; i++) 
        { 
            bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); 
        } 
        return bytes; 
    } 
    catch 
    { 
        return new byte[] { }; 
    } 
}


Here how you would use the methods after splitting the PNPDeviceID

byte[] bytes = this.GetHexStringBytes(split[2]); 
string serial = this.ReverseSerialNumber(Encoding.UTF8.GetString(bytes));

Notes:

If the serial number was generated by PnP service then the split[2] element needs to be handled differently. To examine the split[2] value to see if the value was generated by PnP service use the following if statement below:

if (split[2][1] == '&')

Please make sure you read the follow up article to this.

Happy Coding!