Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0651: Alternative Datenströme einer Datei ermitteln

 von 

Beschreibung 

Mit diesem Tipp ist es möglich die alternativen Datenströme (alternate data streams) einer Datei zu ermitteln. Diese Datenströme existieren nur bei Partitionen die mit NTFS oder HFS formatiert sind.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

BackupRead, BackupSeek, CloseHandle, CreateFileA (CreateFile)

Download:

Download des Beispielprojektes [4,05 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Projekt1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Verzeichnisauswahlliste "Dir1"
' Steuerelement: Dateiauswahlliste "File1"
' Steuerelement: Festplattenauswahlliste "Drive1"
' Steuerelement: Beschriftungsfeld "lblStreams"
' Steuerelement: Beschriftungsfeld "Label3"
' Steuerelement: Beschriftungsfeld "lblFilename"
' Steuerelement: Beschriftungsfeld "Label1"

Option Explicit

Private Sub Dir1_Change()
    File1.Path = Dir1.Path
End Sub

Private Sub Drive1_Change()
    Dir1.Path = Drive1.Drive
End Sub

Private Sub File1_Click()
    If File1.ListIndex > -1 Then
        Dim FullFilename As String
        
        FullFilename = File1.Path
        If Right(FullFilename, 1) <> "\" Then
            FullFilename = FullFilename & "\"
        End If
        FullFilename = FullFilename & File1.FileName
        
        lblFilename.Caption = FullFilename
        lblStreams.Caption = ListStreams(FullFilename)
    Else
        lblFilename.Caption = ""
        lblStreams.Caption = ""
    End If
End Sub

Private Sub Form_Resize()
    ' Ein paar Größenanpassungen, wenn es mehr Daten gibt
    If Me.ScaleWidth > lblFilename.Left Then
        lblFilename.Width = Me.ScaleWidth - lblFilename.Left
    End If
    If Me.ScaleWidth > lblStreams.Left Then
        lblStreams.Width = Me.ScaleWidth - lblStreams.Left
    End If
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'--- Anfang Modul "modNTFSStreams" alias modNTFSStreams.bas ---


'reading NTFS File Streams including the ADS (Alternate Data Streams)
'by Daniel Aue 11.2004
'use at your own risk

Option Explicit

Private Declare Function BackupRead Lib "kernel32.dll" ( _
        ByVal hFile As Long, ByVal lpBuffer As Long, _
        ByVal nNumberOfBytesToRead As Long, _
        ByRef lpNumberOfBytesRead As Long, ByVal bAbort As Long, _
        ByVal bProcessSecurity As Long, ByRef lpContext As Long) As Long

Private Declare Function BackupSeek Lib "kernel32.dll" ( _
        ByVal hFile As Long, ByVal dwLowBytesToSeek As Long, _
        ByVal dwHighBytesToSeek As Long, _
        ByRef lpdwLowByteSeeked As Long, _
        ByRef lpdwHighByteSeeked As Long, _
        ByRef lpContext As Long) As Long

Private Declare Function CreateFile Lib "kernel32.dll" _
        Alias "CreateFileA" (ByVal lpFileName As String, _
        ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
        ByVal lpSecurityAttributes As Long, _
        ByVal dwCreationDisposition As Long, _
        ByVal dwFlagsAndAttributes As Long, _
        ByVal hTemplateFile As Long) As Long

Private Declare Function CloseHandle Lib "kernel32.dll" _
        (ByVal hObject As Long) As Long

Private Type WIN32_STREAM_ID
    dwStreamID As Long
    dwStreamAttributes As Long
    dwStreamSizeLow As Long
    dwStreamSizeHigh As Long
    dwStreamNameSize As Long
End Type

Private Const GENERIC_READ As Long = &H80000000
Private Const FILE_SHARE_READ As Long = &H1
Private Const FILE_FLAG_BACKUP_SEMANTICS = &H2000000
Private Const OPEN_EXISTING As Long = 3
Private Const INVALID_HANDLE_VALUE = -1

Private Const BACKUP_DATA As Long = &H1
Private Const BACKUP_EA_DATA As Long = &H2
Private Const BACKUP_SECURITY_DATA As Long = &H3
Private Const BACKUP_ALTERNATE_DATA As Long = &H4
Private Const BACKUP_LINK As Long = &H5
Private Const BACKUP_PROPERTY_DATA As Long = &H6
Private Const BACKUP_OBJECT_ID As Long = &H7
Private Const BACKUP_REPARSE_DATA As Long = &H8
Private Const BACKUP_SPARSE_BLOCK As Long = &H9

Public Function ListStreams(Filespec As String) As String
    Dim hFile As Long
    Dim udtStreamID As WIN32_STREAM_ID
    Dim lBytesRead As Long
    Dim lContext As Long
    Dim sResult As String
    Dim sStreamName As String
    
    Dim lSeekedLow As Long
    Dim lSeekedHigh As Long
    
    'open the file or directory:
    hFile = CreateFile(Filespec, GENERIC_READ, FILE_SHARE_READ, _
            0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
    If hFile = INVALID_HANDLE_VALUE Then
        Err.Raise Err.LastDllError, , "Can't open file!"
    End If
    
    
    Do
        'read the first stream ID Block:
        If BackupRead(hFile, VarPtr(udtStreamID), LenB(udtStreamID), _
            lBytesRead, 0, 0, lContext) = 0 Then
            
            Err.Raise Err.LastDllError, , "Cant Read Streams!"
        End If
        
        If lBytesRead > 0 Then
            sResult = sResult & vbCrLf
            'figure out the Type of the Stream:
            Select Case udtStreamID.dwStreamID
            Case BACKUP_DATA
                sResult = sResult & "BACKUP_DATA: "
            Case BACKUP_EA_DATA
                sResult = sResult & "BACKUP_EA_DATA: "
            Case BACKUP_SECURITY_DATA
                sResult = sResult & "BACKUP_SECURITY_DATA: "
            Case BACKUP_ALTERNATE_DATA
                sResult = sResult & "BACKUP_ALTERNATE_DATA: "
            Case BACKUP_LINK
                sResult = sResult & "BACKUP_LINK: "
            Case BACKUP_PROPERTY_DATA
                sResult = sResult & "BACKUP_PROPERTY_DATA: "
            Case BACKUP_OBJECT_ID
                sResult = sResult & "BACKUP_OBJECT_ID: "
            Case BACKUP_REPARSE_DATA
                sResult = sResult & "BACKUP_REPARSE_DATA: "
            Case BACKUP_SPARSE_BLOCK
                sResult = sResult & "BACKUP_SPARSE_BLOCK: "
            Case Else
                Err.Raise 513, , "Invalid StreamID!"
            End Select
         
            'is it a named stream ?
            If udtStreamID.dwStreamNameSize > 0 Then
                'then read the name:
                sStreamName = Space(udtStreamID.dwStreamNameSize / 2)
                BackupRead hFile, ByVal StrPtr(sStreamName), udtStreamID.dwStreamNameSize, _
                    lBytesRead, 0, 0, lContext
                sResult = sResult & "'" & sStreamName & "' "
            End If
         
            'Translate the Size of the stream via a double into a string
            sResult = sResult & CStr(LargeInt2Double(udtStreamID.dwStreamSizeLow, _
                udtStreamID.dwStreamSizeHigh)) & _
                    " Bytes."
        
            'seek across the stream data to the next stream ID Block:
            Call BackupSeek(hFile, udtStreamID.dwStreamSizeLow, udtStreamID.dwStreamSizeHigh, _
                lSeekedLow, lSeekedHigh, lContext)
        End If
    
    Loop While lBytesRead > 0
    
    'close the Backup context:
    If BackupRead(hFile, ByVal 0, 0, ByVal 0, 1, 0, lContext) = 0 Then
        Err.Raise Err.LastDllError, , "Can't close BackupRead Context!"
    End If
    
    'close the file:
    If CloseHandle(hFile) = 0 Then
        Err.Raise Err.LastDllError, , "Can't close file!"
    End If
    
    If Len(sResult) > 0 Then
        'zab the leading crlf:
        ListStreams = Mid(sResult, 3)
    End If
End Function


Private Function LargeInt2Double(LowInt As Long, HighInt As Long) As Double
    'Translate a C++ LARGE_INTEGER into a Double
    Dim fResult As Double
    fResult = LowInt
    If fResult < 0 Then
        fResult = fResult + 4294967296# '&h100000000
    End If
    If HighInt < 0 Then
        fResult = fResult + (CDbl(HighInt) + 4294967296#) * 4294967296#
    Else
        fResult = fResult + HighInt * 4294967296#
    End If
    LargeInt2Double = fResult
End Function

'--- Ende Modul "modNTFSStreams" alias modNTFSStreams.bas ---
'-------------- Ende Projektdatei Projekt1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 1 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von _Fire_Dragon_ am 17.04.2005 um 13:43

Hier http://www.pcwelt.de/know-how/tipps_tricks/betriebssysteme/windows/allgemein/108676/ etwas um auch Streams zu erstellen und (alle) auszulesen.
PS: Hab Win2000Prof und VB6SP6 und der Code läuft!