Problem getting HDD C:\ Drive Serial -- Not as easy a fix as you might think!

Posted on 2005-03-02
Medium Priority
Last Modified: 2010-05-02
Okay, a bunch of you are in here thinking you're going to get a quick 500 points... Not so quick!

Here is the Problem: I have been using the code below in a client's application. The purpose of the code is to get the C:\ Drive's serial number to base a unique ID off of. How we use the Unique ID is not the issue. The issue is that approximately .01 percent of the installs return not "ESB-4321" or whatever the serial might be, but instead return only "0". Now, if this happened every time I would know I did something wrong -- but it only happens in 2-3 out of 1,000 installs. So, what could be causing this? If the case is that some systems are unable to return HDD serial, then the problem is not with the code. But if all systems absolutely return HDD serial, then the problem is in the code, but would be hard to pinpoint since it is so anomalous.

Here is the code I am using:

Public Function GetSerialNumber() As String

    Dim Serial As Long, VName As String, FSName As String, TempSerial As String
    'Create buffers
    VName = String$(255, Chr$(0))
    FSName = String$(255, Chr$(0))
    'Get the volume information -- yes, I already declared this function in the module
    GetVolumeInformation "C:\", VName, 255, Serial, 0, 0, FSName, 255
    'Strip the extra chr$(0)'s
    VName = Left$(VName, InStr(1, VName, Chr$(0)) - 1)
    FSName = Left$(FSName, InStr(1, FSName, Chr$(0)) - 1)
    TempSerial = Trim(Str$(Serial))
    GetSerialNumber = TempSerial

End Function

It has also been suggested that I use the FileSystemObject to get the HDD serial, like this (not my code):

Dim fso As New FileSystemObject
Dim drv As Drive
Set drv = fso.GetDrive(fso.GetDriveName("c:"))
MsgBox "Serial number of c: " & drv.SerialNumber

The problem is, if I don't figure out what the problem is with my original code, then I can't assure the client that the problem is fixed just because I used a whole new untested code.

Question by:timothyspriggs
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
  • +3
LVL 28

Expert Comment

ID: 13445087
Are the drives that it fails on SCSI drives as opposed to IDE?
LVL 37

Expert Comment

by:Harisha M G
ID: 13445113
Hi timothyspriggs,
    SCSI drives also have numbers... but they may not return


Author Comment

ID: 13445133
Could be, but I have no way of knowing. Do you have a suspicion that could be the problem? Have you ever read of or heard of that being a problem? Now, if that is it, I wonder if there is a way to determin programmatically whether the drive is SCSI or IDE? And if so, is there a way to get a unique ID from a SCSI drive.

Another thought -- could an IDE RAID cause this problem?
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 37

Expert Comment

by:Harisha M G
ID: 13445145
>> Another thought -- could an IDE RAID cause this problem?
Likely no

Author Comment

ID: 13445166

I see your point that it may not return a number to GetVolumeInformation -- but surely there has to be a way to get the number -- otherwise, how does the bios know how to boot? And if info is available to the bios, doesn't it also have to be available to Windows through an interface? What I mean is this: when you use Windows to create / format a partition on a SCSI drive, wouldn't you think that Windows has access to the serial numbers?

-- Tim
LVL 14

Expert Comment

ID: 13445221
This is what ALLAPI.NET's API-GUIDE notes about it :

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

The getlasterror function is like this :

Private Declare Function GetLastError Lib "kernel32" () As Long
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
Private Sub Form_Load()
    Dim Buffer As String
    Buffer = Space(200)
    FormatMessage FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, GetLastError, LANG_NEUTRAL, Buffer, 200, ByVal 0&
    MsgBox Buffer
End Sub

Try to catch a detailed message instead of guessing the hardware's installed
LVL 28

Expert Comment

ID: 13445825
The only reason I can imagine: does user have access to root directory (c:\)? If no, fso'll also fail

Expert Comment

ID: 13445840
Here is the function I use and it works on both SCSI and IDE Drives. (just tested both)  Drive letter is hard coded but that can be changed to meet your needs

Private Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long

Public Function HardSerial() As Long
    Dim Buf$, Name$, Flags&, Length&
    Dim Serial As Long
    GetVolumeInformation "C:\", Buf$, 255, Serial, Length, Flags, Name$, 255
    HardSerial = Serial
End Function
LVL 28

Accepted Solution

Ark earned 2000 total points
ID: 13445929
GetVolumeInformation returns not HDD serial (aka VendorID), but volume serial. So it works not with physical drives, but with logical volumes instead. In this case there is no difference physical nature of drive (SCSI, IDE, CD, Floppy, RAID, USB device etc. etc.) for this function. The only problem may be (IMHO) - you have no access to this logical volume.
LVL 28

Expert Comment

ID: 13446127
From MSDN:


[out] Pointer to a variable that receives the volume serial number.
This parameter can be NULL if the serial number is not required.
Windows 95/98/Me: If the queried volume is a network drive, the serial number will not be returned.

Author Comment

ID: 13446299
Ark! You are everywhere today! Thanks for stopping by.

Okay, I always ask for Drive C:\ -- I don't think that C:\ can ever be a network drive (though I have been wrong before.) And as for not having access to the logical drive, how can the user not have access to drive C:\? Could it be possible that you have to have administrative privileges just to get the volume serial of your own boot partition?

And Ark, you're going to make feel guilty if you keep answering my questions! I will have to mail you a coupon for beer -- or if you are under 21, root beer.

-- Tim

Author Comment

ID: 13446308
Thanks for that test, rdwillet. So now we know for sure that it isn't a SCSI problem.

Author Comment

ID: 13446503
So, the answer is: there is no answer?  :-)

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question