Forum: PC-Programmierung in VB6 wie direkt an Sektoren einer SD-Karte kommen?


von beta-frank (Gast)


Lesenswert?

Hallo!

Kurzform:
---------

Wie kann man in VB6 gezielt auf Sektoren (...Daten) einer formatierten
oder auch unformatierten SD/MMC-Karte lesend/schreibend zugreifen?

Ausführlicher:
--------------

Bisher bin ich mehr in der Hardwareprogrammierung Zuhause. Nun muß ich
doch an Windows ran. Eine SD-Card dient als Datenaustauschmedium
zwischen Mikrocontroller <-> PC. Um für die an sich einfache Anwendung
ein schnelles Ergebnis zu erzielen, werde ich VB6 nehmen. Ein
spezielles Problem dabei:

Ich möchte per PC auf Daten einer SD-Card zugreifen (lesen/schreiben).
Allerdings müßte ich direkt die Sektoren adressieren können, da es kein
Filesystem auf den Karten gibt (Mikrokontroller soll ohne
FAT-Schnickschnack mit der Karte umgehen können). An eine Lösung mit
ner großen, leeren Textdatei hab ich schon gedacht, gefällt mir aber
nicht aus verschiedenen Gründen.

Danke für Tips oder Links, Frank

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Unter den ernstgemeinten Windows-Versionen kann man Laufwerke als "raw
devices" ansprechen. Das geschieht durch Verwendung recht normaler
Win32-API-Funktionen, was auch aus VB heraus möglich sein sollte.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp
beschreibt die Win32-API-Funktion CreateFile; im Abschnitt "Physical
Disks and Volumes" ist die spezielle Syntax für den Dateinamen ganzer
physikalischer oder logischer Laufwerke beschrieben.

Mit GetFileSize kann die Größe einer solchen "Datei" bestimmt werden
- das sollte die Größe der Speicherkarte sein.

Dann sollte mit ReadFile oder WriteFile blockweise (in Blöcken à 512
Byte) auf das Laufwerk zugegriffen werden - das war's dann auch
schon.

Viel Erfolg.

von beta-frank (Gast)


Lesenswert?

Hi Rufus,

klasse Starthilfe! Als "C"-Konsolenanwendung schon mal testweise ein
Sektor erfolgreich gelesen/angezeigt :-)

Dankeschön - Frank:-)

von Rolf (Gast)


Lesenswert?

Hi Frank,

habe genau dasselbe Vorhaben wie Du. Möchte auch direkt auf die
Sektoren einer SD Karte lesend und schreiben zugreifen. Am besten mit
VB6.
Allerdings habe ich noch nicht viel Erfahrung mit VB und weiß nicht so
recht wie das mit der API - CreateFile Funktion geht.
Könntest Du mir da behilflich sein und mir mal Dein Projekt zuschicken
wenn Du was geschrieben hast.


Vielen Dank

Rolf

von beta-frank (Gast)


Lesenswert?

Hi Rolf,

VB und überhaupt Windows-Programmierung ist auch für mich Neuland.
Schau mal im unteren Drittel von Rufu's Link. Unter dem fettgedrucktem
"Physical Disks and Volumes" gibts den Link:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/calling_deviceiocontrol.asp
Der führt zu Quelltext, allerdings in "C". Aber wenn man sich
írgendein VB6-Beispiel mit Dateibenutzung anschaut, dürfte schnell klar
sein, wie das in VB6 gemacht werden muß.

Ausgehend von dem Quelltext lt. Link habe ich noch ne Funktion
dazugebastelt, um Sektor 0 in nem DOS-Fenster darzustellen. Den
Funktionsaufruf z.B in der Main-Funktion über der letzten Zeile
"return ((int)bResult);" einfügen: "print_sector();"

Die Funktion selbst unter der Zeile "#include <stdio.h>"
reinkopieren.

Gruß Frank
1
void print_sector(void){
2
#define nBytesToRead 512
3
   CHAR inBuffer[512];
4
   int nBytesRead, cnt;
5
   HANDLE hDevice;               // handle to the drive to be examined
6
7
8
   hDevice = CreateFile("\\\\.\\c:", 
9
                    GENERIC_READ ,    // access to the drive
10
                    FILE_SHARE_READ | // share mode
11
                    FILE_SHARE_WRITE, 
12
                    NULL,             // default security attributes
13
                    OPEN_EXISTING,    // disposition
14
                    0,                // file attributes
15
                    NULL);            // do not copy file attributes
16
17
   if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
18
     return;
19
20
   if(ReadFile(hDevice, &inBuffer, nBytesToRead, &nBytesRead, NULL)){
21
//Wenn erfolgreich nach inBuffer[] gelesen
22
      printf("\nSektor 0 auf Platte C:\n");
23
      for(cnt=0; cnt<512; cnt++)
24
         if(inBuffer[cnt] >= ' ')        //falls Zeichen darstellbar
25
(ASCII>=32) ist
26
            printf("%c",inBuffer[cnt]);
27
      printf("\n");
28
   }
29
30
   CloseHandle(hDevice);
31
   return;
32
}

von Sobczak (Gast)


Lesenswert?

Aus Erfahrung: für solche Anwendungen ist VB nicht das beste.
Meine Empfehlung wäre DELPHI - einfach zu beherrschen und fähig wie C.
Das Quellcode von oben könnte man fast 1:1 übernehmen und Oberfläche
baut man so einfach wie mit VB.

von Rolf (Gast)


Lesenswert?

Hi Frank,

vielen Dank für die rasche Antwort. Werd mich jetzt mal mit den
Dateizugriffen in VB beschäftigen müssen.
Bin jetzt grad auf einem anderen Lösungsweg für mein Problem. Schreib
die Daten mit dem uc jetzt in eine Datei (FAT16), so läßt es sich mit
dem PC leichter verarbeiten. Das schreiben mit dem uc klappt schon
recht gut, muß jetzt nur mal noch schauen obs mit dem lesen auch so gut
gelingt.

Gruß Rolf.

von Alex (Gast)


Lesenswert?

Ein interessanter Effekt den ich gefunden habe:

Wenn man unter Windows mittels SetFilePointer(...) gezielt einzelne
Sektoren einer Karte lesen möchte, so liefert die API keinen Fehler
zurück, wenn man auf Sektoren weit jenseits der Kartengröße zugreift.
Habe allerdings noch nicht rausbekommen, was ReadFile(...) dann
eigentlich ausliest.

GetFileSize(...) liefert bei meinem USB-Stick leider nur -1
(0xFFFFFFFF) zurück. GetLastError() erzählt mir was von Fehler 87
(ERROR_INVALID_PARAMETER). Komisch ist nur, dass ReadFile und WriteFile
klappen.

von Alex (Gast)


Lesenswert?

Oder muss man für sowas DeviceIoControl(...) nutzen? Das erscheint mir
nur noch etwas umfangreicher zu werden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.