Strange results with GetVolumeInformation

When I use GetVolumeInformation with the following functions with certian drives serial numbers I get results like this:

454D-7E11 will return 454D-700000000000
1141-6D18 will return 1141-6000000000000000000

Are these serial numbers invalid or is there a bug in the code?

Heres the code I don't remember where I got it from:

                ' Add to a module
                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

                'Add the following code to the form

                Public Function SerialNumber(ByVal Pathname As String) As String

                    Dim r As Long
                    Dim DrvVolumeName As String
                    Dim DrvSerialNo As String
                    rgbGetVolumeInformationRDI Pathname$, DrvVolumeName$, DrvSerialNo$
                     SerialNumber = DrvSerialNo$
                    '     'show the results
                End Function

                Private Sub rgbGetVolumeInformationRDI(Pathname$, DrvVolumeName$, DrvSerialNo$)

                    '     'create working variables
                    '     'to keep it simple, use dummy variables for info
                    '     'we're not interested in right now
                    Dim r As Long
                    Dim pos As Integer
                    Dim HiWord As Long
                    Dim HiHexStr As String
                    Dim LoWord As Long
                    Dim LoHexStr As String
                    Dim VolumeSN As Long
                    Dim MaxFNLen As Long
                    Dim UnusedStr As String
                    Dim UnusedVal1 As Long
                    Dim UnusedVal2 As Long
                    '     'pad the strings
                    DrvVolumeName$ = Space$(14)
                    UnusedStr$ = Space$(32)
                    '     'do what it says
                    r& = GetVolumeInformation(Pathname$, _
                    DrvVolumeName$, Len(DrvVolumeName$), VolumeSN&, _
                    UnusedVal1&, UnusedVal2&, UnusedStr$, Len(UnusedStr$))
                    '     'error check
                    If r& = 0 Then Exit Sub
                    '     'determine the volume label
                    pos% = InStr(DrvVolumeName$, Chr$(0))
                    If pos% Then DrvVolumeName$ = Left$(DrvVolumeName$, pos% - 1)
                    If Len(Trim$(DrvVolumeName$)) = 0 Then DrvVolumeName$ = "(no label)"
                    '     'determine the drive volume id
                    HiWord& = GetHiWord(VolumeSN&) And &HFFFF&
                    LoWord& = GetLoWord(VolumeSN&) And &HFFFF&
                    HiHexStr$ = Format$(Hex(HiWord&), "0000")
                    LoHexStr$ = Format$(Hex(LoWord&), "0000")
                    DrvSerialNo$ = HiHexStr$ & "-" & LoHexStr$
                End Sub

                Private Function GetHiWord(dw As Long) As Integer


                    If dw& And &H80000000 Then
                        GetHiWord% = (dw& \ 65535) - 1
                    Else: GetHiWord% = dw& \ 65535
                    End If

                End Function

                Private Function GetLoWord(dw As Long) As Integer


                    If dw& And &H8000& Then
                        GetLoWord% = &H8000 Or (dw& And &H7FFF&)
                    Else: GetLoWord% = dw& And &HFFFF&
                    End If

                End Function

Neal HartmanAsked:
Who is Participating?
Erick37Connect With a Mentor Commented:
Comment as answer, thanks!
'One of many ways, to do it.  Look Ma, no math!

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)

' Return the low word of a Long value
Function GetLoWord(ByVal value As Long) As Integer
CopyMemory GetLoWord, value, 2
End Function

' Return the high word of a Long value.
Function GetHiWord(ByVal value As Long) As Integer
CopyMemory GetHiWord, ByVal VarPtr(value) + 2, 2
End Function
No, just do this:

Instead of
HiHexStr$ = Format$(Hex(HiWord&), "0000")
LoHexStr$ = Format$(Hex(LoWord&), "0000")

HiHexStr$ = Right("0000" & Hex(HiWord&), 4)
LoHexStr$ = Right("0000" & Hex(LoWord&), 4)
Neal HartmanAuthor Commented:
I tried both solutions and only Erick37's worked. Answer the Q Erick and I'll send you the points. Thanks to both of you for a quick response.
This question was awarded, but never cleared due to the JSP-500 errors of that time.  It was "stuck" against userID -1 versus the intended expert whom you awarded.  This corrects the problem and the expert will now receive these points; points verified.

Please click on your Member Profile and select "View Question History" to navigate through any open or locked questions you may have to update and finalize them.  If you are an EE Pro user, you can also choose Power Search to find all your open questions.

This is the Community Support link, if help is needed, along with the link to All Topics which reflects many TAs recently added.

In efforts to help all Members maintain their open questions, this is a reminder to click your Member Profile, expand your question history and find/update all your Open and Locked questions.
Thank you,
Moderator @ Experts Exchange
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.