|
Ein Datenträger wird lässt sich durch eine beim Formatieren vergebene Seriennummer identifizieren. Zwar ist diese Seriennummer alles andere als eindeutig - die Zahl der alljährlich formatierten Disketten und gebrannten CD-ROMs dürfte den möglichen Wertebereich (lediglich Long) locker überfordern. Aber zur Unterscheidung zwischen verschiedenen Datenträgern innerhalb des tagesüblichen Umfeldes eines Rechners reicht die Seriennummer allemal aus: Es ist doch recht unwahrscheinlich, dass einem zwei Mal die gleiche Nummer in die Quere kommt.
Den Long-Wert der Seriennummer liefert die API-Funktion GetVolumeInformation in ihrem vierten Parameter, wenn Sie ihr den Laufwerksbuchstabe (mit abschließendem ":") im ersten Parameter übergeben.
Üblicherweise wird die Seriennummer jedoch nicht als blanke Zahl dargestellt, sondern als 8-stelliger Hexadezimal-Wert in zwei 4er-Gruppen, etwa wie "08DF-D5D5". Dazu muss der Long-Wert der Seriennummer in zwei Integer-Bestandteile ("Word") zerlegt werden ("HiWord" und "LoWord"). Am einfachsten können Sie dies mittels zweier benutzerdefinierter Variablen erledigen. Die eine enthält ein Element des Datentyps Long, die andere zwei Elemente des Datentyps Integer. Füttern Sie das Long-Element der einen Variablen mit dem Long-Wert der Seriennummer und weisen Sie anschließend diese Variable einer Variablen mit den zwei Integer-Elementen zu, werden die Bytes des Long-Elements direkt 1:1 in die Bytes der Integer-Elemente umkopiert. Nun brauchen Sie nur noch die beiden Integer-Werte in Hexadezimal-Werte zu konvertieren und gegebenenfalls mit führenden Nullen zu versehen, um zwei 4-stellige Gruppen zu erhalten. Als Trennzeichen ist der einfache Bindestrich üblich - Sie können natürlich auch einen Doppelpunkt oder was auch immer dazwischen setzen.
Die folgende Funktion VolumeSerial entledigt Sie der Gefahr, einen der vielen Parameter der API-Funktion GetVolumeInformation falsch zu belegen und vereinfacht die Übergabe der Laufwerksbezeichnung. Sie können einen Laufwerksbuchstaben von "A" bis "Z" (bzw. von "a" bis "z", oder auch eine komplette Pfadangabe) oder eine Laufwerksnummer von 0 bis 25 übergeben. Beide Arten der Angabe werden in einen eindeutigen Laufwerksbuchstaben mit abschließendem ":" zum Aufruf umgesetzt. Sollte diese Umsetzung scheitern, wird ein Laufzeitfehler (Fehler-Nr. 5 - "Ungültiger Prozeduraufruf oder ungültiges Argument") ausgelöst. Bei Erfolg wird die Seriennummer als Long-Wert zurückgegeben. Bei Misserfolg wird der Laufzeitfehler Nr. 68 ("Gerät nicht verfügbar") ausgelöst.
Private Type IntLongType
i1 As Integer
i2 As Integer
End Type
Private Type LongType
l As Long
End Type
Private Declare Function GetVolumeInformation Lib "Kernel32" Alias _
"GetVolumeInformationA" (ByVal RootPath As String, _
ByVal VolumeNameBuffer As String, _
ByVal VolumeNameSize As Integer, VolumeSerialNumber As Long, _
MaximumComponentLength As Long, FileSystemFlags As Long, _
ByVal FileSystemNameBuffer As String, _
ByVal FileSystemNameSize As Long) As Long
Public Function VolumeSerial(Volume As Variant) As Long
Dim nVolume As String
Dim nSerial As Long
Dim nRet As Long
If IsNumeric(Volume) Then
Select Case Volume
Case 0 To 25
nVolume = Chr$(CInt(Volume) + 65)
Case Else
Err.Raise 5
End Select
ElseIf VarType(Volume) = vbString Then
nVolume = LCase$(Left$(Volume, 1))
Select Case nVolume
Case "a" To "z"
Case Else
Err.Raise 5
End Select
Else
Err.Raise 5
End If
nRet = GetVolumeInformation(nVolume & ":", vbNullString, 0, _
nSerial, 0, 0, vbNullString, 0)
If nRet = 0 Then
Err.Raise 68
Else
VolumeSerial = nSerial
End If
End Function
Die Funktion VolumeSerialHex gibt die oben beschriebene Hexadezimal-Darstellung der Seriennummer als String zurück. Auch ihr können Sie einen Laufwerksbuchstaben, einen Pfad oder eine Laufwerksnummer übergeben. Dazu können Sie noch optional das Trennzeichen zwischen den beiden Gruppen angeben - voreingestellt ist der Bindestrich ("-").
Public Function VolumeSerialHex(Volume As Variant, _
Optional Separator As String = "-") As String
Dim nL As LongType
Dim nI As IntLongType
nL.l = VolumeSerial(Volume)
LSet nI = nL
VolumeSerialHex = Right$("0000" & Hex$(nI.i2), 4) & Separator _
& Right$("0000" & Hex$(nI.i1), 4)
End Function
|