Link to home
Start Free TrialLog in
Avatar of LeighWardle
LeighWardleFlag for Australia

asked on

VB6: Trouble getting correct Volume Serial Number from Windows API function GetVolumeInformation

Hi Experts,

I'm trying to use the Windows API function GetVolumeInformation located in kernel32 to read the Volume Serial Number for drive C:.

For my system it reports the Volume Serial Number = -1131000883.
But this is not the correct Volume Serial Number (=3163966413) - as given both by an equivalent program in Fortran 95 and also the output from the DOS command VOL C:

My code is shown below.

Can anyone tell me what I'm doing wrong?

Thanks, Leigh


Option Explicit


Public Declare Function GetVolumeInformation& Lib "kernel32" _
Alias "GetVolumeInformationA" _
(ByVal lpRootPathName As String, ByVal pVolumeNameBuffer As String, _
ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, _
lpMaximumComponentLength As Long, lpFileSystemFlags As Long, _
ByVal lpFileSystemNameBuffer As String, _
ByVal nFileSystemNameSize As Long)
Public Const MAX_FILENAME_LEN = 256


Public Function DriveSerial(ByVal sDrv As String) As Long

'  Volume Serial Number of a Partition (uses Windows API function, GetVolumeInformation).

'            * On Surface4: confirmed by C:\>vol C:
'                               Volume in drive C is Windows
'                               Volume Serial Number is BC96-4BCD  (BC964BCD)
'                               (converting from Hex to Decimal gives 3163966413, not -1131000883)

'Usage:
'Dim ds As Long
'ds = DriveSerial("C")
     Dim RetVal As Long
     Dim str As String * MAX_FILENAME_LEN
     Dim str2 As String * MAX_FILENAME_LEN
     Dim a As Long
     Dim b As Long
     Call GetVolumeInformation(sDrv & ":\", str, _
          MAX_FILENAME_LEN, RetVal, _
          a, b, str2, MAX_FILENAME_LEN)
     DriveSerial = RetVal 'Surface4: -1131000883
End Function

Open in new window

Avatar of Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3]
Flag of Luxembourg image

please try to return it like this
DriveSerial = Val("&H" & RetVal )
Avatar of LeighWardle

ASKER

Hi Guy,

Sorry,

DriveSerial = Val("&H" & RetVal )

Gives DriveSerial = 0  (RetVal =  -1131000883.
Interestingly:

Hex$(RetVal) = "BC964BCD"  which is the correct Hex value
then this should work:

DriveSerial = Val("&H" & Hext$(RetVal ))
I assume Hext$ is a typo and should be Hex$.

DriveSerial = Val("&H" & Hex$(RetVal )) gives  -1131000883 which is what I started with.
ASKER CERTIFIED SOLUTION
Avatar of Guy Hengel [angelIII / a3]
Guy Hengel [angelIII / a3]
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just a thought.
Are we confusing the Volume serial number (as assigned by the operating system) with the Drive serial number from the manufacturer.

This is from the MSDN:

"This function returns the volume serial number that the operating system assigns when a hard disk is formatted. To programmatically obtain the hard disk's serial number that the manufacturer assigns, use the Windows Management Instrumentation (WMI) Win32_PhysicalMedia property SerialNumber."
Hi GrahamSkan,

I'm after the Volume serial number (as assigned by the operating system).
Hi Guy,

Can you please provide Declarations for these variables?:

   hword
   lword
   HiHexStr
   LoHexStr
I am on mobile now, its in the linked page...
Guy:

Sorry, I cannot see the linked page...
Guy:

Thanks, I have the linked page...
Hi Guy,

I needed to declare:

   Dim strDriveSerial As String

then I had:

   strDriveSerial = HiHexStr & "-" & LoHexStr

That gives strDriveSerial = "FFFFBC96-4BCD"
That's very much like what I got using Hex$(RetVal)

Hex$(RetVal) = "BC964BCD"  which is the correct Hex value
Guy said earlier:

>> Long (long integer)       4 bytes       -2,147,483,648 to 2,147,483,647
>> and you want to get 3163966413 as value, which is "too high" for that, hence the "negative"
>> representation

Clearly I cannot store a number as big as 3163966413 in a 4 byte "long" variable.

My Fortran program uses an 8 byte variable which can store 3163966413.
I think the solution to my problem is to leave the VB6 code as it was when I posted the question.

And to modify my Fortran 95 code to give the same answers as the VB6 code,
Thanks Guy for your expert comments and for your persistance!

You said earlier:

>> Long (long integer)       4 bytes       -2,147,483,648 to 2,147,483,647
>> and you want to get 3163966413 as value, which is "too high" for that, hence the "negative"
>> representation

Clearly I cannot store a number as big as 3163966413 in a 4 byte "long" variable.

My Fortran program uses an 8 byte variable which can store 3163966413.

So the solution to my problem is to leave the VB6 code as it was when I posted the question.

And to modify my Fortran 95 code to give the same answers as the VB6 code,