Home

HD.exe: kleine Optimierungen

Testerei mit input, StdIn,
fwrite, fprint, exist, fcreate, fclose

MASM32 - Infoseite

MASM32-SDK (Dateizugriffe bei Windows Konsolapplikationen):
Übersicht: Zugriffe auf benannte Dateien

Die auf dieser Seite gemachten Angaben sind aus der Dokumentation des MASM32-SDKs nach flüchiger Übersetzung zusammengestellt worden. Sie enthalten möglicherweise Fehler. Betrachten Sie diese Seite deshalb als Übersetzungshilfe und verwenden Sie vorzugsweise die beim MASM32-SDK mitgelieferte Dokumentation!
Für Dateizugriffe ist das Zusammenspiel zwischen Applikationsprogramm und Betriebssystem unverzichtbar. Im MASM32-SDK steht hierfür eine umfangreiche - und leider etwas unübersichtliche - Sammlung von Makros und Prozeduren zur Verfügung. Diese Seite beinhaltet eine Zusammenfassung aus der beim MASM32-SDK mitgelieferten Dokumentation.

Vorbemerkung: Die Dateimacros sind in einer ASCII- und in einer UNICODE- Version verfügbar. Die Namen der UNICODE- Version unterscheiden sich von den Namen der ASCII-Version durch ein nachgestelltes „W”.

Beispiele dazu:
fcreate Erzeugt eine neue Datei und meldet dessen Zugriffsnummer (Handle) zurück. Damit ist die neu angelegte Datei geöffnet.
fcreateW Die UNICODE- Version von fcreate.


File IO Macros aus High Level Macro Help / Macro Categories / File IO Macros

Load and Save Complete File (Laden und Speichern der vollständigen Datei)

Die Dateilängen müssen in Bytes angegeben werden. Jedes UNICODE-Zeichen belegt zwei Bytes, jedes ASCII-Zeichen belegt ein Byte.

InputFile liest die gesamte Datei in einen Speicherbereich (memory buffer).
OutputFile schreibt einen Speicherbereich als Datei auf den Datenträger.
bytecount Längenangabe in Bytes
Fehlermeldung: Wenn Fehler auftrat, ist der Rückgabewert FALSE (0). Fehlermeldung kann mit GetLastError() geprüft werden.
Übungsbeispiel in Die ganze Datei lesen und schreiben: InputFile und OutputFile

Je nachdem, ob die ASCII- oder UNICODE-Version spezifiziert ist, muss auch der Dateiname in ASCII oder UNICODE angegeben werden. Für die Direktangabe (Literal) in ASCII ist das Makro „ascii()” zuständig. Für die Direktangabe in UNICODE ist „uni$()” oder „uc$()” zuständig. Wenn eine Stringadresse statt einer Direktangabe erfolgt, muss auch der String passend in ASCII oder UNICODE codiert sein. Es gibt insgesamt sechs verschiedene File IO Macros:

Die sechs File IO Macros
Datei lesen:mov hMem, InputFile(dateiname)wertet die Definition __UNICODE__ aus
mov hMem, InputFileA(dateiname)nur für ASCII
mov hMem, InputFileW(dateiname)nur für UNICODE
Datei schreiben:mov rval, OutputFile(dateiname,lpmem,flen) wertet die Definition __UNICODE__ aus
mov rval, OutputFileA(dateiname,lpmem,flen) nur für ASCII
mov rval, OutputFileU(dateiname,lpmem,flen) nur für UNICODE
InputFile - liest die gesamte Datei in einen Speicherbereich (memory buffer)
mov hMem, InputFile(dateiname)

Parameter:
1. dateiname ist der Dateiname als Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
Rückgabewert: Die Adresse des Speicherpuffers in den der Dateinhalt geladen wurde. Die Dateilänge wird im ECX-Register zurückgegeben.

Hinweis: Vor Aufruf von InputFile soll überprüft werden, ob die Datei vorhanden ist. Nach Bearbeitung der Datei soll der belegte Speicherpuffer durch Anwendung des Makros free freigegeben werden.

Beispiel:

mov hMem, InputFile("privatdatei.txt")
mov flen, ecx
; hier Programmcode
free hMem
Applikationsbeispiel in HD.exe - hexadezimale Dateianzeige
OutputFile - schreibt einen Speicherbereich als gesamte Datei auf einen Datenträger
mov rval, OutputFile(dateiname,lpmem,flen)

Parameter:
1. dateiname ist der Dateiname als Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
2. lpmem ist die Adresse des Speicherbereich der in die Datei zu schreiben ist
3. flen ist die Anzahl der zu schreibenden Bytes
Rückgabewert: Bei erfolgreicher Ausführung von 0 verschieden. Anzahl der von der Datei gelesenen Bytes.

Hinweis: Das Makro überschreibt eine bestehende Datei gleichen Namens. Da der Rückgabewert im EAX-Register steht, kann er im Quellprogramm so geschrieben werden, als ob es das EAX-Register wäre.

Beispiel dazu:

test OutputFile("neuedatei.txt",pbuffer,flen), eax
  jnz @F
  ; hier sollte auf den Fehler eingegangen werden
@@:

Low Level File Operations aus High Level Macro Help / Macro Categories / File IO Macros

Diese Makros sind in einer ASCII- und in einer UNICODE- Version verfügbar
  • fcreate - erzeugt eine neue Datei und meldet ihre Zugriffsnummer (Handle) zurück
  • fdelete - löscht eine Datei
  • fopen - öffnet eine bestehende Datei und meldet ihre Zugriffsnummer (Handle) zurück
  • fclose - schließt eine offene Datei
  • fread - liest Daten von einer geöffneten Datei
  • fwrite - schreibt Daten in eine geöffnete Datei
  • fprint - schreibt eine Zeile in eine geöffnete Datei
  • fprintc - schreibt C-formatierten Text in eine geöffnete Datei
  • fseek - positioniert innerhalb der geöffneten Datei auf eine bestimmte Position
  • fseteof - setzt das Dateiende an die aktuelle Position der geöffneten Datei
  • fsize - ermittelt die Größe einer geöffneten Datei in Bytes
In den folgenden Kurzbeschreibungen bedeutet
  • hFile: Dateizugriffsnummer (Handle)
  • filename: Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
  • bcnt: Zähler bzw. Längenangabe in Bytes
  • lpMemory: Zeiger auf den Pufferspeicher

fcreate - Erzeugt eine neue Datei und meldet ihre Zugriffsnummer (Handle) zurück
mov hFile, fcreate(filename)

Parameter:
1. filename
Rückgabewert: Zugriffsnummer der erzeugten Datei oder Fehlermeldung

Hinweis: Durch die Erzeugung der Datei wird sie im Update-Modus eröffnet.

Beispiel: mov hFile, fcreate("mynewfile.ext")
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Testerei mit input, StdIn, fwrite, fprint, exist, fcreate, fclose

Nachfolgend die Makro-Definition aus masm32/macros.asm:

; ---------------------------------------------------------------------
; create a new file with read / write access and return the file handle
; ---------------------------------------------------------------------
fcreate MACRO filename
    invoke CreateFileA,reparg(filename),GENERIC_READ or GENERIC_WRITE,
                      NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
    EXITM <eax>       ;; return file handle
    ENDM
fdelete - löscht eine Datei
cmp fdelete(filename), 0

Parameter:
1. dateiname
Rückgabewert: Bei erfolgreicher Ausführung von 0 verschieden. Andernfalls Fehlermeldung

Dies Makro ruft die Windows API DeleteFile() auf.

Beispiel: cmp fdelete("tempfile.ext"), 0 jne @F print "Schade, das hat nicht geklappt",13,10 @@:
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Testerei mit input, StdIn, fwrite, fprint, exist, fcreate, fclose

fopen - öffnet eine bestehende Datei und meldet ihre Zugriffsnummer (Handle) zurück
mov hFile, fopen(filename)

Parameter:
1. dateiname
Rückgabewert: Zugriffsnummer der geöffneten Datei oder Fehlermeldung

Beispiel: mov hFile, fopen("liesmich.txt")
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Direktes Update von Sätzen einer Direktzugriffsdatei

Nachfolgend die Makro-Definition aus masm32/macros.asm:

; -------------------------------------------------------------------------
; open an existing file with read / write access and return the file handle
; -------------------------------------------------------------------------
fopen MACRO filename
    invoke CreateFileA,reparg(filename),GENERIC_READ or GENERIC_WRITE,
                      NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
    EXITM <eax>       ;; return file handle
    ENDM
fclose - schließt eine offene Datei
fclose hFile

Parameter:
1. Zugriffsnummer der noch geöffneten Datei.
Rückgabewert: Bei erfolgreicher Ausführung von 0 verschieden. Anzahl der von der Datei gelesenen Bytes.

Beispiel: fclose hFile
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Testerei mit input, StdIn, fwrite, fprint, exist, fcreate, fclose

fread - liest Daten von einer geöffneten Datei
mov bDaten, fread(hFile,lpMemory,bcnt)

Parameter:
1. hFile Zugriffsnummer der geöffneten Datei
2. lpMemory ist Adresse des Pufferspeichers, in den die gelesenen Daten zwischenzuspeichern sind
3. bcnt Anzahl der maximal zu lesenden Bytes. Der Pufferspeicher darf nicht kleiner als bcnt angelegt worden sein.
Rückgabewert: Anzahl der von der Datei gelesenen Bytes.

Beispiel: mov bDaten, fread(hFile,lpMemory,bytecount)
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm

fwrite - schreibt Daten in eine geöffnete Datei
mov bwritten, fwrite(hFile,lpMemory,bcnt)

Parameter
1. hFile Zugriffsnummer der geöffneten Datei
2. lpMemory ist Adresse des Pufferspeichers, in den die zu schreibenden Daten zwischenzuspeichern sind.
3. bcnt Anzahl der zu schreibenden Bytes. Der Pufferspeicher darf nicht kleiner als bcnt angelegt worden sein.
Rückgabewert: Anzahl der zur Datei geschriebenen Bytes oder Fehlermeldung

Beispiel: mov bwritten, fwrite(hFile,lpmemory,bytecount)
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Testerei mit input, StdIn, fwrite, fprint, exist, fcreate, fclose

fprint - schreibt eine Zeile in eine geöffnete Datei
fprint hFile,lptext

Parameter:
1. hFile Zugriffsnummer der geöffneten Datei 2. lptext Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
Rückgabewert: kein Rückgabewert

Dies Makro ergänzt einen Zeilenvorschub (13,10) am Zeilende. Es ist dazu bestimmt, Textzeilen sequentiell auszugeben.

Beispiel: fprint hFile,"Dies ist eine Zeile voller Text"
Übungsbeispiel in Testerei mit input, StdIn, fwrite, fprint, exist, fcreate, fclose

fprintc - Schreibt C-formatierten Text in eine geöffnete Datei
fprintc hFile,"Hi Guys\n"

Parameter:
1. hFile Zugriffsnummer der geöffneten Datei
2. lpText Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette. Die Strings können Escapesequenzen im Stil von C enthalten (z.B. \n für CRLF, \t für Tabulator). Siehe dazu das Makro cfm$ in /masm32/macros/macros.asm
Rückgabewert: kein Rückgabewert
Übungsbeispiel in Testerei mit lineout$ und Dateizugriff über Zwischenpuffer

fseek - positioniert innerhalb der geöffneten Datei auf eine bestimmte Position
mov cloc, fseek(hFile,distance,location)

Parameter:
1. hFile Zugriffsnummer der geöffneten Datei
2. distance Die Anzahl Bytes, um die die Position geändert werden soll. Negative und positve Angaben sind möglich. number of bytes to move.
3. location Von wo aus die Postion geändert werden soll. Hier lässt sich angeben: FILE_BEGIN, FILE_END oder FILE_CURRENT für die aktuelle Position innerhalb der Datei.

Beispiel setzt die Position auf 100 ab Dateianfang: mov cloc, fseek(hFile,100,FILE_BEGIN)
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Direktes Update von Sätzen einer Direktzugriffsdatei

fseteof - setzt das Dateiende an die aktuelle Position der geöffneten Datei
fseteof hFile

Parameter:
1. hFile Zugriffsnummer der geöffneten Dateibr> Rückgabewert: kein Rückgabewert

fseteof wird normalerweie zum Abschneiden / Verkürzen der Datei verwendet

Beispiel: fseteof hFile

fsize - ermittelt die Größe einer geöffneten Datei in Bytes
mov flen, fsize(hFile)

Parameter:
1. hFile Zugriffsnummer der geöffneten Datei
Rückgabewert: Dateilänge in Bytes
Hinweis: rv(filesize,ADDR fname) liefert die Dateilänge der angebenen Datei in EAX. Die Datei muss dazu nicht geöffnet sein.

File Functions aus der MASM32 Library Reference

Die Datei \masm32\lib\masm32.lib ist eine Sammlung von zusätzlichen Prozeduren. Um diese Prozeduren nutzen zu können, müssen diese zwei Zeilen im Assemblerprogramm vorhanden sein: include \masm32\include\masm32.inc includelib \masm32\lib\masm32.lib

Die Prozeduren sind:

  • exist - ist die Datei vorhanden?
  • filesize - ermittle die Dateigröße
  • read_disk_file - lese Datei in Speicherpuffer
  • write_disk_file - schreibe Datei von Speicherpuffer
  • LoadList - lade Dateienamen in eine Listbox
exist - ist die Datei vorhanden?
exist dateiname
Parameter:
dateiname ist der Dateiname als Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
Rückgabewert: 0 wenn die Datei nicht exstiert, andernfalls 1
Beispiel:
.if rv(exist,ADDR fname) == TRUE        ;Datei vorhanden?                ; test if file 
    ; Hier Bearbeitung der Datei
.else
    print   "Schade, diese Datei wurde nicht gefunden",13,10
.endif
Applikationsbeispiel in \masm32\examples\exampl07\fileio\ppfileio.asm
Übungsbeispiel in Testerei mit input, StdIn, fwrite, fprint, exist, fcreate, fclose
filesize - ermittle die Dateigröße
Parameter:
dateiname ist der Dateiname als Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
Rückgabewert -1 wenn die Datei nicht exstiert, andernfalls steht in EAX die Dateigröße in Bytes.
Hinweis: Die Dateigröße wird ermittelt, ohne dass die Datei geöffnet wird. Zwei Beispiele:
mov	bytecount, rv(filesize,chr$("\masm32\include\windows.inc")) 
mov bytecount, rv(filesize,ADDR dateiname) 

Applikationsbeispiel in fn und rv unterstützen invoke
read_disk_file - lese Datei in Speicherpuffer
read_disk_file proc dateiname,lpMem,lpLen
Parameter:
1. dateiname ist der Dateiname als Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
2. lpMem Die Adresse einer DWORD-Variablen mit dem Startadresse des Speicherpuffer
3. lpLen Die Adresse einer DWORD-Variablen mit der Anzahl der in den Speicherpuffer zu schreibenden Bytes
Rückgabewert: 0 wenn der Schreibzugriff nicht erfolgreich war, andernfalls nicht 0

Hinweis: Wenn der Inhalt des Speicherpuffers nicht mehr benötigt wird, sollte lpMem mit GlobalFree() freigegeben werden.
write_disk_file - schreibe Datei vom Speicherpuffer
write_disk_file proc dateiname,lpData,fl
Parameter:
1. dateiname ist der Dateiname als Zeiger auf einen ASCII-String mit 0 als Endemarkierung oder eine in doppelte Gänsefüßchen eingekleidete Zeichenkette
2. lpData Die Adresse einer DWORD-Variablen mit dem Startadresse des Speicherpuffers
3. fl ist eine DWORD-Variable mit der Anzahl der in den Speicherpuffer zu schreibenden Bytes
Rückgabewert: Anzahl der in die Datei geschriebenen Bytes; 0 falls ein Fehler auftrat

Hinweis: Die Prozedur ist dazu bestimmt, bei jedem Aufruf eine komplette Datei zu schreiben. Eine vorhandene Datei gleichen Namens wird dabei überschrieben.

LoadList - lade Dateinamen in eine Listbox
LoadList hWin,pattern:DWORD Lädt Dateinamen des aktuellen Verzeichnisses in eine Listbox.
Parameter:
1. hWin ist das „handle” des Eltern-Fensters (parent window)
2. pattern lpPattern ist die Adresse eines ASCII-Strings mit 0 als Endemarkierung. Er enthält die Auswahlmaske mit der die zu benutzenden Dateien spezifiziert werden.
Rückgabewert: Es gibt keinen Rückgabewert

Das aktuelle Verzeichnis kann mit dem API-Funktionsaufruf SetCurrentDirectory() gesetzt werden.

File Dialogs für die grafische Oberfläche (GUI) unter Windows

OpenFileDlg - zeige Dialog zum Dateiöffnen und melde die ausgewählte Datei zurück
mov fname, OpenFileDlg(hWin,hInstance,lpTitle,lpPattern)
Parameter:
1. hWin ist das „handle” des Eltern-Fensters (parent window)
2. hInstance ist das „Instance handle” der Applikation
3. lpTitle ist die Adresse eines ASCII-Strings mit 0 als Endemarkierung
4. lpPattern ist die Adresse eines ASCII-Strings mit 0 als Endemarkierung. Er enthält die Auswahlmaske mit der die zu benutzenden Dateien spezifiziert werden.
Rückgabewert: Die Adresse eines 260 Bytes langen Puffers mit den ausgewählten Dateinamen. Falls das erste Byte im Puffer eine 0 ist, dann wurde nichts ausgewählt.

Hinweis: Die Auswahlmaske erwartet Namen und Muster durch 0 getrennt. Zwei Nullen hintereinander geben das Ende der Maske an.

Beispiele zum Hinweis:

.data
 pattern db "Text Files",0,"*txt",0,"Ini Files",0,"*ini",0,0
.code

Außerdem kann genutzt werden:

 sas pattern, "All files",0,"*.*",0

Beispiel:

mov fname, OpenFileDlg(hWnd,hInstance,"Öffne eine neue Datei",ADDR pattern)
cmp  BYTE PTR [eax], FALSE ; ist das erste Byte 0? (0=FALSE)
jne  @F                    ; nicht FALSE, also richtig
; hier Programmschritte zur Fehlerbehandlung
@@:
SaveFileDlg - zeige Dialog zum Dateispeichern und melde den ausgewählte Dateinamen zurück
mov fname, SaveFileDlg(hWin,hInstance,lpTitle,lpPattern)
Parameter:
1. hWin ist das „handle” des Eltern-Fensters (parent window)
2. hInstance ist das „Instance handle” der Applikation
3. lpTitle ist die Adresse eines ASCII-Strings mit 0 als Endemarkierung
4. lpPattern ist die Adresse eines ASCII-Strings mit 0 als Endemarkierung. Er enthält die Auswahlmaske mit der die zu benutzenden Dateien spezifiziert werden.
Rückgabewert: Die Adresse eines 260 Bytes langen Puffers mit den ausgewählten Dateinamen. Falls das erste Byte im Puffer eine 0 ist, dann wurde nichts ausgewählt.

Hinweis: Die Auswahlmaske erwartet Namen und Muster durch 0 getrennt. Zwei Nullen hintereinander geben das Ende der Maske an.

Beispiele zum Hinweis:

.data
  pattern db "Text Files",0,"*txt",0,"Ini Files",0,"*ini",0,0
.code

Außerdem kann genutzt werden:

 sas pattern, "All files",0,"*.*",0

Beispiel:

  mov fname, SaveFileDlg(hWnd,hInstance,"Save File As ...",ADDR pattern)
  cmp BYTE PTR [eax], FALSE ; ist das erste Byte 0? (0=FALSE)
  jne @F                    ; nicht FALSE, also richtig
; hier Programmschritte zur Fehlerbehandlung
@@:
GetFile - Vorbereiter Dialog zur Dateiauswahl
Die Einrichtung eines Dialogs ist wohl eine mühsame Angelegenheit. Deshalb wurde ein Dialog vorbereitet, der die Programmierung erleichtert. Der Dialog „GetFile” dient dazu, eine Datei in einem vorgegebenen Verzeichnis auszuwählen. Es werden weder Laufwerk noch Verzeichnis angezeigt. Die angezeigten Dateinamen sind sortiert. Sie werden durch eine Auswahlmaske ausgewählt.

Die Beschreibung steht in der interaktiven Hilfe unter „Pre-Built Dialogs”.

GetFile proc Parent:DWORD,Instance:DWORD,Icon:DWORD,caption:DWORD,directory:DWORD,pattern:DWORD,buffer:DWORD
Parameter:
1. Parent ist das „handle” des Eltern-Fensters (parent window)
2. Instance ist das „Instance handle” der Applikation
3. Icon ist das „handle” des Icons der Applikation
4. caption ist ein ASCII-Strings mit 0 als Endemarkierung. Er wird im oberen Fensterrahmen als Überschrift angezeigt. 5. directory ist ein ASCII-Strings mit 0 als Endemarkierung. Er gibt das anzuzeigende Verzeichnis an.
6. pattern ist die Adresse eines ASCII-Strings mit 0 als Endemarkierung. Er enthält die Auswahlmaske mit der die zu benutzenden Dateien spezifiziert werden. 7. buffer ist die Adresse eines Speicherpuffers. Er sollte 260 Bytes groß sein, um auch Dateinamen der Maximallänge aufnehmen zu können.
Rückgabewert: EAX ist immer 0. Falls im 260 Bytes langen Puffer steht der ausgewählte Dateinamen. Falls das erste Byte im Puffer eine 0 ist, dann wurde nichts ausgewählt.

Letztes Upload: 17.02.2019 um 15:54:33