vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Erstellen von dynamischen Kontextmen?s - wann immer Sie sie brauchen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

Visual-Basic Einsteiger
Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 12.06.09 13:12

Hallo zusammen,

Ich suche eine Möglichkeit mit VB6 gezielt Sektoren einer SD-Karte zu beschreiben. Diese möchte ich anschließend mit einem Microcontroller auslesen. Ich möchte damit Daten von meinem VB-Programm zu meiner Selbstbau-CNC-Fräse übertragen.

Ich bin dabei noch in der Entwicklung. Bisher habe ich die Möglichkeit gefunden einfach unter Windows eine Textdatei anzulegen mit einem eindeutigen Schlüsselwort am Anfang und dann den Daten. Dann musste der Microcontroller einen Sektor nach dem andern nach dem Schlüsselwort durchsuchen, damit er wusste wo die Daten liegen. Wenn ich die Daten gezielt in Sektoren schreiben könnte würde der µC entlastet.

Ich hoffe es kann mir jemand helfen!

Gruß
Marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 13.06.09 00:28

Hallo,

inzwischen bin ich ein kleines Stückchen weiter:

Ich habe hier ein PDF gefunden, das zumindesteinmal erklärt, wie man die einzelnen Sektoren aus VB heraus lesen kann. Um zu kontrollieren, ob er richtig liest habe ich hier ein Programm gefunden, das das auch kann (etwa bei 2/3 der Seite: SD_RAW.exe).

Hier mal mein Programm:
In einem Modul habe ich den Code aus dem PDF platziert.
Was dieser Code genau macht kapiere ich nicht wirklich

in der Form:
Dim buffer(512) As Byte
Dim akt_sektor As Integer
 
Private Sub Command1_Click()
GetDriveHandle "e:"
End Sub
 
Private Sub Command2_Click()
CloseDriveHandle
End
End Sub
 
Private Sub Command3_Click()
akt_sektor = akt_sektor + 1
List1.Clear
Dim i As Integer
ReadSectorFromDrive buffer()
sektor_anzeigen
End Sub
 
 
Private Sub Command4_Click()
Dim i As Integer
For i = 1 To 10
  ReadSectorFromDrive buffer()
  akt_sektor = akt_sektor + 1
Next i
sektor_anzeigen
End Sub
 
Private Sub Command5_Click()
Dim i As Integer
Dim j As Integer
For i = 0 To 1000
  ReadSectorFromDrive buffer()
  akt_sektor = akt_sektor + 1
  If buffer(0) = 60 Then
    sektor_anzeigen
    Exit Sub
  End If
Next i
End Sub
 
Sub sektor_anzeigen()
Dim i As Integer
List1.Clear
For i = 0 To 511
    List1.AddItem (Hex(buffer(i)))
Next i
Text1.Text = akt_sektor
End Sub
 
Private Sub Form_Load()
akt_sektor = -1
End Sub
Erklärungen:
Command1 stellt das Handle zum Laufwerk her.
Command2 löscht das Handle und beendet das Programm
Command3: bei jedem klick wird der nächste Sektor ausgelesen und angezeigt
Command4: bei jedem klick werden 10 Sektoren übersprungen
Command5 sucht die Sektoren ab, bis er am ersten Byte die Zahl 60 findet (erstes Zeichen meines Schlüsselwortes)


Das ganze funktioniert FAST. Er findet die Daten zwar und zeigt sie auch an, aber im falschen Sektor! In meinem Fall liegt das gesuchte zeichen in Sektor 771 (das sagt der µC un SD_RAW.exe). Jedoch findet mein Programm das im Sektor 520. Nach nochmaligem Formatieren und Datei neu anlegen findet der µC die Stelle in Sektor 8019 und mein Programm bei 7768. Also beide male 251 weniger. Wo könnten diese 251 herkommen???

Hat jemand eine Idee wie man das zum schreiben erweitern könnte. Dazu habe ich leider noch nichts gefunden

Ich hoffe ihr könnte mir helfen!!

Gruß
Marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 14.06.09 00:20

Ich bins nochmal....

Ich hab jetzt gemerkt, dass Sektor 0 meines Programms Sektor 251 des anderen Programms entspricht. Also liest er bei dem ersten Aufruf der Funktion "ReadSectorFromDrive" gleich Sektor 251 ein anstatt 0. Woran könnte das liegen?

Hier mal mein Code aus dem Modul:
'Windows-Variablen / Konstanten:
Private Type OVERLAPPED
    Internal                As Long
    InternalHigh            As Long
    offset                  As Long
    OffsetHigh              As Long
    hEvent                  As Long
End Type
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000003
Private Const OPEN_EXISTING = 3
Private Const INVALID_HANDLE_VALUE = -1
Private Const FILE_DEVICE_FILE_SYSTEM = &H9
Private Const METHOD_BUFFERED = 0
Private Const FILE_READ_DATA = (&H1)
Private Const FILE_WRITE_DATA = (&H2)
'API-Deklarationen
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
    (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, lpSecurityAttributes As Any, _
    ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes _
    As Long, _
    ByVal hTemplateFile As Long) As Long
 
Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
         lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
         lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
 
Private Declare Function CloseHandle Lib "kernel32" _
    (ByVal hObject As Long) As Long
'Im Modul benötigt:
Dim lngFileHandle As Long       'Handle für Drive
Dim CreateFileError 'Fehler beim Erzeugen des Handles
Dim ReadFileError 'Fehler beim Lesen vom Laufwerk
 
Sub GetDriveHandle(Drivename$)
'muss zuerst aufgerufen werden um Zugang zum Drive zu bekommen
'Fehlervariablen zurücksetzen
CreateFileError = 0
ReadFileError = 0
FileName$ = "\\.\" & Drivename$
lngFileHandle = CreateFile(FileName$, GENERIC_READ Or GENERIC_WRITE, _
  FILE_SHARE_READ, ByVal 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, ByVal 0)
 
    'Bei Fehlschlag aussteigen2
    If (lngFileHandle = INVALID_HANDLE_VALUE) Then
        MsgBox "Invalid handle!"
        CreateFileError = 1
        Exit Sub
    Else
        'MsgBox "File handle:" & Str$(lngFileHandle)
    End If
 
End Sub
 
Sub ReadSectorFromDrive(buffer() As Byte)
'liest 512 Bytes (1 Sektor) in buffer() ein
    If CreateFileError Then
        ReadFileError = 1
        Exit Sub
    End If
 
    retReadFile& = ReadFile(lngFileHandle, buffer(0), 512, BytesRead&, 0&)
    If retReadFile& = 0 Then
        MsgBox "Readfile returns " & Str$(retReadFile&) & vbCrLf & "Read Error!"
        ReadFileError = 1
        Exit Sub
    End If
End Sub
 
Sub CloseDriveHandle()
CloseHandle lngFileHandle
End Sub
Das Schreiben der Sektoren wäre mir eigentlich viel wichtiger. Das lesen bräuchte ich höchstens um das geschriebene zu überprüfen (falls Sektoren defekt sind).
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 14.06.09 22:38

und nochmal ich

Ich hab jetzt im Modul folgendes Hinzugefügt:

Declare Function WriteFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef _
  lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, ByRef _
  lpNumberOfBytesWritten As Long, ByRef lpOverlapped As Long) As Long
 
Sub WriteSectorToDrive(buffer() As Byte)
'schreibt 512 Bytes (1 Sektor) von buffer()
    If CreateFileError Then
        ReadFileError = 1
        Exit Sub
    End If
 
    retwriteFile& = WriteFile(lngFileHandle, buffer(0), 512, BytesWrite&, 0&)
    If retReadFile& = 0 Then
        MsgBox "Readfile returns " & Str$(retReadFile&) & vbCrLf & "Read Error!"
        ReadFileError = 1
        Exit Sub
    End If
End Sub
Außerdem habe ich in der Funktion "GetDriveHandle" eine Zeile so geändert um auch Schreibzugriff zu haben:

lngFileHandle = CreateFile(FileName$, GENERIC_READ Or GENERIC_WRITE, _
  FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0, OPEN_EXISTING, _
  FILE_ATTRIBUTE_NORMAL, ByVal 0)
Außerdem habe ich in der Form noch folgenden Code hinzugefügt um die neue Funktion zu testen:

Private Sub Command6_Click()
Dim i As Integer
For i = 0 To 254
  puffer(i) = i
Next i
WriteSectorToDrive puffer()
End Sub
Leider funktioniert es wieder nur FAST. Wenn ich Command6 drücke schmiert das Programm ab mit der Fehlermeldung: "Visual Basic hat ein Problem festgestellt und muss beendet werden." Wenn ich anschließend mit dem anderen Programm anschließend Sektor 251 anschaue steht dort alles richtig drin. Also hat die Funktion soweit eigentlich funktioniert.

Mit diesen Funktionen kann ich ja aber auch immer nur von vorne her die Sektoren der Reihe nach beschreiben. Gibt es auch eine Möglichkeit, dass ich z.B. sage "Schreibe buffer() in Sektor 1254"? Um die anderen Daten nicht zu löschen müsste ich ja sonst jeden Sektor einlesen und das eingelesene wieder schreiben um "voranzukommen".

Sektor 251 scheint übrigens etwas wichtiges zu sein, denn windows sagt jetzt wenn ich die SD-Karte öffnen will, dass diese nicht formatiert ist.

Gruß
marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 15.06.09 17:35

Nachdem ich jetzt hier etwas gefunden habe wollte ich es mal mit der API SetFilePointer versuchen und hab folgendes hinzugefügt:

im Modul:
Private Const FILE_BEGIN = 0
Declare Function SetFilePointer Lib "kernel32.dll" (ByVal hFile As Long, ByVal _
  lDistanceToMove As Long, ByRef lpDistanceToMoveHigh As Long, ByVal _
  dwMoveMethod As Long) As Long
 
Sub SelectSector(adress As Long)
'Wählt den zu beschreibenden oder zu lesenden Sektor aus
    adress = adress * 512
    If CreateFileError Then
        ReadFileError = 1
        Exit Sub
    End If
    retReadFile& = SetFilePointer(lngFileHandle, adress, FILE_BEGIN, 0&)
    If retReadFile& = 0 Then
        MsgBox "Readfile returns " & Str$(retReadFile&) & vbCrLf & "Read Error!"
        ReadFileError = 1
        Exit Sub
    End If
End Sub
und in der Form:
Private Sub Command7_Click()
  Dim adress As Long
  adress = Text2.Text
  SelectSector adress
End Sub
Das funktioniert leider überhaupt nicht Er schreibt immernoch in Sektor 251 und die Fehlermeldung kommt auch noch. Kann das daran liegen, dass die geöffnete Datei keine größe hat (weil sie neu erstellt wird) und man den Zeiger nur innerhalb der Datei verschieben kann? Wenn ja, gibt es auch eine API, mit der man die Datei vergrößern kann ohne den Inhalt zu verändern, oder eine API mit der man direkt den Startpunkt der Datei festlegen kann?

Außerdem habe ich mir mal die API OpenFile angeschaut, werde dabei aber daraus nicht schlau:
Zitat:

lpReOpenBuff Erwartet eine "OFSTRUCT"-Struktur die mit Informationen zu der geöffneten Datei gefüllt wird.


Kann das jemand Anfängergerecht erklären?

Vielen Dank im Voraus!

Gruß
Marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 16.06.09 08:22

Hi

Kann man vielleicht direkt beim Aufruf von CreateFile den Speicherort der Datei festlegen? Also bei
FileName$ = "\\.\" & Drivename$"
irgendwie noch den Sektor mit angeben?
Geht das irgendwie?

Oder geht das ganz anders?

Gruß
Marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 16.06.09 20:40

irgendwie wird das eine One-Man-Show.

Könnte ich es evtl. so machen, dass ich eine Datei anlege, die die komplette Größe der SD-Karte einnimmt (bei mir 2Gb). Dann könnte ich darin rumschreiben wie ich möchte. Würde das irgendwie gehn? Wenn ja, wie? Hat da jemand einen Tip?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Arne Elster
Datum: 16.06.09 22:00

Wenn das Setzen der neuen Position geglückt ist,
gibt dir SetFilePointer die von dir gewünschte Position zurück,
in dem Fall den Wert deiner Variablen "adress".
Wenn SetFilePointer fehlschlägt, ist der Rückgabewert -1.

Zu dem Sektor 251 könnte ich mir vorstellen,
dass Windows dich nur auf die Partition auf der SD Karte zugreifen lässt,
weil du die diese öffnest mit \\.\X:
Und die fängt halt bei 251 an. Mal als Theorie.

OpenFile brauchst du dir nicht anzugucken,
die wurde von Microsoft als obsolet erklärt,
wird nicht mehr verwendet. CreateFile ist die neue.


Zurück zur 251:
Folgendes ist eine nicht geprüfte mögliche Lösung.
Ich hab das direkt hier ins Antwortfeld reingeschrieben und nicht getestet.
Zunächst mal brauchst du folgenden Code, kopier den in ein Modul:

Private Declare Function DeviceIoControl Lib "kernel32" ( _
                         ByVal hDevice As Long, _
                         ByVal dwIoControlCode As Long, _
                         ByRef lpInBuffer As Any, _
                         ByVal nInBufferSize As Long, _
                         ByRef lpOutBuffer As Any, _
                         ByVal nOutBufferSize As Long, _
                         ByRef lpBytesReturned As Long, _
                         ByRef lpOverlapped As Any) As Long
 
Private Type STORAGE_DEVICE_NUMBER
    DeviceType As Long
    DeviceNumber As Long
    PartitionNumber As Long
End Type
 
Private Const IOCTL_STORAGE_GET_DEVICE_NUMBER As Long = &H2D1080
 
Public Function GetPhysDriveNumber(ByVal hDrv As Long) As Long
    Dim udtSDN As STORAGE_DEVICE_NUMBER
    Dim lngRet As Long
 
    If DeviceIoControl(hDrv, IOCTL_STORAGE_GET_DEVICE_NUMBER, ByVal _
        0&, 0&, udtSDN, Len(udtSDN), lngRet, ByVal 0&) Then
        GetPhysDriveNumber = udtSDN.DeviceNumber
    Else
        GetPhysDriveNumber = -1
    End If
End Function
CreateFile gibt dir ja ein Handle auf die Partition zurück,
damit du mit Read/WriteFile darin rumwursteln kannst.
Windows erlaubt dir aber auch, auf ein Speichermedium komplett zuzugreifen,
wenn du als Dateiname für CreateFile "\\.\PHYSICALDRIVEX" angibst,
wobei X eine Nummer von 0 bis 9 ist.
Das Problem ist, wie man rausfindet, zu welcher Nummer Partition X gehört.

Zunächst öffnest du also X mit CreateFile über "\\.\X:".
Das Handle, das dir CreateFile zurückgibt, benutzt du, um GetPhysDriveNumber aufzurufen.
Wenn du das hast, schließt du das Handle mit CloseHandle,
um jetzt CreateFile mit "\\.\PHYSICALDRIVE" plus der von GetPhyDriveNumber zurückgegebenen Zahl ein weiteres mal anzufeuern.
Und mit dem Handle müsstest du dich nun frei auf der SD Karte bewegen können.
Hoffentlich klappts.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Arne Elster
Datum: 16.06.09 22:30

Aber versuch erstmal nur ReadFile mit dem neuen Handle zu benutzen,
um rauszufinden ob du auch wirklich von der SD Karte liest!
Ein schlechtes Zeichen wäre, wenn GetPhysDriveNumber 0 zurückgibt.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 17.06.09 17:54

Hi

Ich hab es jetzt mal so gemacht wie du gemeint hast. Ich bekomm aber immer -1 von der Funktion GetPhysDriveNumber zurück. Ich hab den obenstehenden Code in ein Modul gemacht und dann noch einen Button mit folgendem Code:
Private Sub Command8_Click()
GetDriveHandle "e:"
nummer$ = CStr(GetPhysDriveNumber(lngFileHandle))
CloseDriveHandle
GetDriveHandle2 nummer$
End Sub
Außerdem noch diesen Code im alten Modul ergänzt:
Sub GetDriveHandle2(Drivenummer$)
CreateFileError = 0
ReadFileError = 0
FileName$ = "\\.\PHYSICALDRIVE" & Drivenummer$
lngFileHandle = CreateFile(FileName$, GENERIC_READ Or GENERIC_WRITE, _
  FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0, OPEN_EXISTING, _
  FILE_ATTRIBUTE_NORMAL, ByVal 0)
 
    'Bei Fehlschlag aussteigen2
    If (lngFileHandle = INVALID_HANDLE_VALUE) Then
        MsgBox "Invalid handle!"
        CreateFileError = 1
        Exit Sub
    Else
        MsgBox "File handle:" & Str$(lngFileHandle)
    End If
 
End Sub
Ich habe auch hier ein Projekt gefunden, das auch auf Sektoren zugreifen kann. Damit funktioniert es auch. Zumindest das anzeigen. Auch weiß ich jetzt wieso gerade Sektor 251 bei mir als 0 angezeigt wird und warum er am Anfang immer bei Sektor 771 angefangen hat zu schreiben. Das Programm zeigt mir nämlich unter anderem folgende DriveInfos an:
Zitat:


Hidden Sectors: 251
Number of FAT copies: 2 (Was heißt das??)
Sectors per FAT: 242
FAT copy(1) starts at 4 (Absolut gesehen dann also 255)
FAT copy(2) starts at 246 (entspricht dann 497)
Rootdirectory starts at 488 (entspricht 739)
RootDirectoryLength: 31 (Endet also bei 770)


also kann ich bei 771 anfangen Daten zu schreiben. Er springt auch zu Sektor 520 (also 771 absolut), wenn ich den Datenbereich anzeigen lasse. Damit wäre also das schoneinmal geklärt. Wenn ich den MBR anzeigen lasse zeigt er mir also Sektor 251 an. Könnte es daran liegen, dass ich den MBR überschreibe, dass VB immer einen Fehler produziert wenn ich meine Funktion WriteSectorToDrive aufrufe?

ich habe versucht das Programm zu verstehen, aber das ist mir viel zu komplex. ich kapier das nicht. Ich möchte nur einen String an eine Definierte Position auf der SD-Karte schreiben (und evtl. das geschriebene überprüfen) Eigentlich würde es mir sogar genügen, wenn die Schreibfunktion wenigstens ab Sektor 251 funktionieren würde. Das wäre ja dann eine definierte Position. Funktioniert ja aber leider nicht
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 18.06.09 08:16

Hi,

Ich hab jetzt mal versucht das Programm zu verstehen.
Diese zwei Funktionen sind wohl die wichtigsten für meinen Fall:
Private Function DirectReadDriveNT(ByVal sDrive As String, ByVal iStartSec As _
  Long, ByVal iOffset As Long, ByVal cBytes As Long) As Variant
    Dim hDevice As Long
    Dim abBuff() As Byte
    Dim abResult() As Byte
    Dim nSectors As Long
    Dim nRead As Long
    nSectors = Int((iOffset + cBytes - 1) / BytesPerSector) + 1
    hDevice = CreateFile("\\.\" & UCase(Left(sDrive, 1)) & ":", GENERIC_READ Or _
      GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, _
      0&, 0&)
    If hDevice = INVALID_HANDLE_VALUE Then Exit Function
    Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)
    ReDim abResult(cBytes - 1)
    ReDim abBuff(nSectors * BytesPerSector - 1)
    Call ReadFile(hDevice, abBuff(0), UBound(abBuff) + 1, nRead, 0&)
    CloseHandle hDevice
    CopyMemory abResult(0), abBuff(iOffset), cBytes
    DirectReadDriveNT = abResult
End Function
 
Private Function DirectWriteDriveNT(ByVal sDrive As String, ByVal iStartSec As _
  Long, ByVal iOffset As Long, ByVal sWrite As String) As Boolean
    Dim hDevice As Long
    Dim abBuff() As Byte
    Dim ab() As Byte
    Dim nRead As Long
    Dim nSectors As Long
    nSectors = Int((iOffset + Len(sWrite) - 1) / BytesPerSector) + 1
    hDevice = CreateFile("\\.\" & UCase(Left(sDrive, 1)) & ":", GENERIC_READ Or _
      GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, _
      0&, 0&)
    If hDevice = INVALID_HANDLE_VALUE Then Exit Function
    abBuff = DirectReadDriveNT(sDrive, iStartSec, 0, nSectors * BytesPerSector)
    ab = StrConv(sWrite, vbFromUnicode)
    CopyMemory abBuff(iOffset), ab(0), Len(sWrite)
    Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)
    Call LockFile(hDevice, LoWord(iStartSec * BytesPerSector), HiWord(iStartSec _
      * BytesPerSector), LoWord(nSectors * BytesPerSector), HiWord(nSectors * _
      BytesPerSector))
    DirectWriteDriveNT = WriteFile(hDevice, abBuff(0), UBound(abBuff) + 1, _
    nRead, 0&)
    Call FlushFileBuffers(hDevice)
    Call UnlockFile(hDevice, LoWord(iStartSec * BytesPerSector), HiWord( _
      iStartSec * BytesPerSector), LoWord(nSectors * BytesPerSector), HiWord( _
      nSectors * BytesPerSector))
    CloseHandle hDevice
End Function
Eigentlich sogar nur die Untere ("DirectWriteDriveNT")
Wenn ich es richtig verstanden habe macht die folgendees:
- Ein Handle erzeugen mit in meinem Fall "\\.\e:" (ist genau so wie ich es hatte)
- in abBuff den Sektor (oder die Sektoren) der geschrieben werden soll einlesen (mittels der Funktion darüber)
- Was das hier "ab = StrConv(sWrite, vbFromUnicode)" macht hab ich nicht kapiert, aber glaube nicht dass das so wichtig ist
- Dann wird der zu schreibende String in das vorher ausgelesene an der richtigen Prosition eingefügt.
- Der Filepointer wird auf die Stelle gesetzt an der geschrieben werden soll (hab ich genauso gemacht)
- LockFile wird aufgerufen (hierzu finde ich keine richtige Beschreibung was die API macht. Auf der Seite die ich oben angegeben habe wird die API zwar erwähnt, aber es fehlt jede Beschreibung)
- WriteFile wird ausgeführt (Wie ich es auch gemacht habe)
- FlushFileBuffers(hDevice): damit wird wahrscheinlich der Zwischenpuffer gelehrt (was bringt das??)
- Dann wird die Datei wieder "ungelockt" (auch hierzu hab ich keine Infos gefunden )
- Am Ende wird das Handle wieder geschossen.

Zusammenfassend kann man sagen:
bis auf diese Zeilen:
    Call LockFile(hDevice, LoWord(iStartSec * BytesPerSector), HiWord(iStartSec _
      * BytesPerSector), LoWord(nSectors * BytesPerSector), HiWord(nSectors * _
      BytesPerSector))
 
[....]
 
    Call FlushFileBuffers(hDevice)
    Call UnlockFile(hDevice, LoWord(iStartSec * BytesPerSector), HiWord( _
      iStartSec * BytesPerSector), LoWord(nSectors * BytesPerSector), HiWord( _
      nSectors * BytesPerSector))
ist alles genau so wie ich es hatte. Was bewirken diese 3 Zeilen? Ich hatte gestern abend keine Zeit mehr zu probieren was passiert wenn ich diese Zeilen einfüge und jetzt bin ich bei der Arbeit. Falls es dann funktioniert wüsste ich aber auch gerne wieso.

Gruß
Marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 18.06.09 21:20

Hi

Ich habe jetzt diese 2 Funktionen in ein Neues Projekt kopiert (In ein Modul) und eine Miniform mit folgemdem Code erstellt:

Private Sub Command1_Click()
    Dim Res As Integer
    Res = DirectWriteDriveNT(Drive1.Drive, Text1.Text, Text2.Text, Text3.Text)
    MsgBox Res
End Sub
Text1 enthält den Zielsektor
Text2 Enthält den Offset (wie viele Zeichen am Beginn des Sektors frei bleiben sollen)
Text3 enthält den zu schreibenden Text

UND ES FUNKTIONIERT!!!

Nur hat es einen kleinen Schönheitsfehler: Ich lasse ja den Rückgabewert anzeigen, und der ist "-1". Heißt ja eigentlich, dass es nicht funktioniert hat. Wenn ich es aber mit dem anderen Programm überprüfe hat es doch funktioniert.... Der Text steht genau da wo er stehen soll...

Es funktioniert, aber ich kapiers nicht. Besser als andersrum
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Agrypnie
Datum: 21.06.09 08:08

Hallo Majuz !

Dein Projekt ähnelt meinem fertiggestellten.
Bei mir müssen Bilddaten in Byteform auf der SD-Karte gespeichert werden um sie später mit dem Microcontroller auszulesen und die Bilder auf einem Display darzustellen.

Da mein Zeug nun fertig ist, kannst du dir den Quellcode hier runterladen:
http://funkamateur.de/download/down3.htm
dort lädst du „Grafischer Tageskalender mit DCF77-Funkuhr“ runter

in dem ZIP ist meine EXE und das VB6 Projekt enthalten. Vielleicht hilft es dir etwas.
Wichtig wäre in meinem Projekt für dich der Sub „Write Pic“
Irgendwie sieht das bei mir etwas weniger aus als bei dir.... obwohl bei den ganzen Posts hier blicke ich nun auch nicht soo durch

Gruß: Thomas
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: Majuz
Datum: 21.06.09 10:47

hi

Danke, aber ich habs jetzt auch hinbekommen Bist ein paar Tage zu spät dran

Ich habs jetzt mit diesen beiden Funktionen:
Private Function DirectReadDriveNT(ByVal sDrive As String, ByVal iStartSec As _
  Long, ByVal iOffset As Long, ByVal cBytes As Long) As Variant
    Dim hDevice As Long
    Dim abBuff() As Byte
    Dim abResult() As Byte
    Dim nSectors As Long
    Dim nRead As Long
    nSectors = Int((iOffset + cBytes - 1) / BytesPerSector) + 1
    hDevice = CreateFile("\\.\" & UCase(Left(sDrive, 1)) & ":", GENERIC_READ Or _
      GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, _
      0&, 0&)
    If hDevice = INVALID_HANDLE_VALUE Then Exit Function
    Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)
    ReDim abResult(cBytes - 1)
    ReDim abBuff(nSectors * BytesPerSector - 1)
    Call ReadFile(hDevice, abBuff(0), UBound(abBuff) + 1, nRead, 0&)
    CloseHandle hDevice
    CopyMemory abResult(0), abBuff(iOffset), cBytes
    DirectReadDriveNT = abResult
End Function
 
Private Function DirectWriteDriveNT(ByVal sDrive As String, ByVal iStartSec As _
  Long, ByVal iOffset As Long, ByVal sWrite As String) As Boolean
    Dim hDevice As Long
    Dim abBuff() As Byte
    Dim ab() As Byte
    Dim nRead As Long
    Dim nSectors As Long
    nSectors = Int((iOffset + Len(sWrite) - 1) / BytesPerSector) + 1
    hDevice = CreateFile("\\.\" & UCase(Left(sDrive, 1)) & ":", GENERIC_READ Or _
      GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, _
      0&, 0&)
    If hDevice = INVALID_HANDLE_VALUE Then Exit Function
    abBuff = DirectReadDriveNT(sDrive, iStartSec, 0, nSectors * BytesPerSector)
    ab = StrConv(sWrite, vbFromUnicode)
    CopyMemory abBuff(iOffset), ab(0), Len(sWrite)
    Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)
    Call LockFile(hDevice, LoWord(iStartSec * BytesPerSector), HiWord(iStartSec _
      * BytesPerSector), LoWord(nSectors * BytesPerSector), HiWord(nSectors * _
      BytesPerSector))
    DirectWriteDriveNT = WriteFile(hDevice, abBuff(0), UBound(abBuff) + 1, _
    nRead, 0&)
    Call FlushFileBuffers(hDevice)
    Call UnlockFile(hDevice, LoWord(iStartSec * BytesPerSector), HiWord( _
      iStartSec * BytesPerSector), LoWord(nSectors * BytesPerSector), HiWord( _
      nSectors * BytesPerSector))
    CloseHandle hDevice
End Function
Diese sind sehr allgemein gefasst. Es ist z.B. ein Offset eingebaut und es funktioniert auch für alle Datenlängen. Außerdem wird zuerst gelesen was in diesen Sektoren Liegt die beschrieben werden sollen und dann nur die Teile ersetzt in denen Was geschrieben werden soll, der Rest bleibt so wie es war.

So wie du es hast hatte ich es am Anfang auch, aber es hat nicht funktioniert mit den Filepointer zu verändern. Mir fällt aber gerade auf, dass das CreateFile anders hast als ich. Ich hatte da:
CreateFile(FileName$, GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or _
  FILE_SHARE_WRITE, ByVal 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, ByVal 0)
evtl. liegt es daran, dass ich den Filepointer nicht verändern konnte. Wäre ein Versuch wert. Komm allerdings frühestens heut abend dazu.

Gruß
Marius
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sektoren einer SD-Karte beschreiben (ohne Dateisystem) 
Autor: NormBot
Datum: 05.03.13 22:48

das Thema iss zwar nun schon in die Jahre gekommen, leider ist es schwer etwas zu dem Thema in Google in Deutscher Sprache zu finden.

Die Schreib Funktion für SD Karten hab ich verstanden und Funzt auch Problemfrei, leider klappt es bei mir mit der Lesefunktion nicht da kommt kein Wert zurück

was hat es den mit diesem Offset aufsich ???

wäre um Antworten dankbar !!

vielleicht auch ein Anwendungsbeispiel wie der Lesecode anzuwenden ist


Der hier geht leider nicht
Text1.text = DirectReadDriveNT("\\?\P:", 1, 0, 1)

ich dachte das er in das Feld Text1 den Wert von Sektor 1 an Byte Stelle 1 übernimmt ??!!

DENKFEHLER ??


Gruß Normen
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel