Dateien kopieren.

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Dateien kopieren.

Beitrag von TomCat »

hallo,

hab folgendes Problem. Ich will Dateien eines Verzeichnisses in ein anderes Verzeichnis kopieren. Normalerweise nutze ich die Funktionen des Interrupt 21h um Dateien zu bearbeiten. Dazu muss aber der Dateinname bekannt sein. Ist hier aber nicht der Fall.
Gibt es eine Möglichkeit die Dateinnamen des Verzeichnisses zu erfahren?

THX
TomCat
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Dateien kopieren.

Beitrag von freecrac »

TomCat hat geschrieben:hallo,

hab folgendes Problem. Ich will Dateien eines Verzeichnisses in ein anderes Verzeichnis kopieren. Normalerweise nutze ich die Funktionen des Interrupt 21h um Dateien zu bearbeiten. Dazu muss aber der Dateinname bekannt sein. Ist hier aber nicht der Fall.
Gibt es eine Möglichkeit die Dateinnamen des Verzeichnisses zu erfahren?

THX
TomCat
Na klar gibt es das.

A) Ich glaube zuerst brauchen wir die DTA-Adresse und dann ein "FINDFIRST" -Aufruf.
B) Dann erneut die DTA-Adresse holen und dann "FINDNEXT" aufrufen.
Danach Punkt B solange wiederholen bis der letzte Eintrag geholt wurde.
(Die Einträge sind alle unsortiert.)

RBIL-> inter61b.zip-> INTERRUP.F

Code: Alles auswählen

--------D-212F-------------------------------
INT 21 - DOS 2+ - GET DISK TRANSFER AREA ADDRESS
	AH = 2Fh
Return: ES:BX -> current DTA
Note:	under the FlashTek X-32 DOS extender, the pointer is in ES:EBX
SeeAlso: AH=1Ah
RBIL-> inter61b.zip-> INTERRUP.G

Code: Alles auswählen

--------D-214E-------------------------------
INT 21 - DOS 2+ - "FINDFIRST" - FIND FIRST MATCHING FILE
	AH = 4Eh
	AL = special flag for use by APPEND (refer to note below)
	CX = file attribute mask (see #01420 at AX=4301h) (bits 0 and 5 ignored)
	    0088h (Novell DOS 7) find first deleted file
	DS:DX -> ASCIZ file specification (may include path and wildcards)
Return: CF clear if successful
	    Disk Transfer Area filled with FindFirst data block (see #01626)
	CF set on error
	    AX = error code (02h,03h,12h) (see #01680 at AH=59h/BX=0000h)
Notes:	for search attributes other than 08h, all files with at MOST the
	  specified combination of hidden, system, and directory attributes
	  will be returned.  Under DOS 2.x, searching for attribute 08h
	  (volume label) will also return normal files, while under DOS 3.0+
	  only the volume label (if any) will be returned.
	this call also returns successfully if given the name of a character
	  device without wildcards.  DOS 2.x returns attribute 00h, size 0,
	  and the current date and time.  DOS 3.0+ returns attribute 40h and
	  the current date and time.
	immediately after an INT 2F/AX=B711h (APPEND return found name), the
	  name at DS:DX will be overwritten; if AL=00h on entry, the actual
	  found pathname will be stored, otherwise, the actual found path
	  will be prepended to the original filespec without a path.
	under LANtastic, this call may be used to obtain a list of a server's
	  shared resources by searching for "\\SERVER\*.*"; a list of printer
	  resources may be obtained by searching for "\\SERVER\@*.*"
	under the FlashTek X-32 DOS extender, the filespec pointer is in DS:EDX
BUGS:	under DOS 3.x and 4.x, the second and subsequent calls to this function
	  with a character device name (no wildcards) and search attributes
	  which include the volume-label bit (08h) will fail unless there is
	  an intervening DOS call which implicitly or explicity performs a
	  directory search without the volume-label bit.  Such implicit
	  searches are performed by CREATE (AH=3Ch), OPEN (AH=3Dh), UNLINK
	  (AH=41h), and RENAME (AH=56h)
	DR DOS 3.41 and 5.0 return the Directory attribute for the volume label
SeeAlso: AH=11h,AH=4Fh,AX=4301h,AX=714Eh,AX=71A1h,AX=F257h/SF=02h
SeeAlso: INT 2F/AX=111Bh,INT 2F/AX=B711h

Format of FindFirst data block:
Offset	Size	Description	(Table 01626)
---PC-DOS 3.10, PC-DOS 4.01, MS-DOS 3.2/3.3/5.0---
 00h	BYTE	drive letter (bits 0-6), remote if bit 7 set
 01h 11 BYTEs	search template
 0Ch	BYTE	search attributes
---DOS 2.x (and some DOS 3.x???)---
 00h	BYTE	search attributes
 01h	BYTE	drive letter
 02h 11 BYTEs	search template
---WILDUNIX.COM---
 00h 12 BYTEs	15-character wildcard search pattern and drive letter (packed)
 0Ch	BYTE	search attributes
---DOS 2.x and most 3.x---
 0Dh	WORD	entry count within directory
 0Fh	DWORD	pointer to DTA???
 13h	WORD	cluster number of start of parent directory
---PC-DOS 4.01, MS-DOS 3.2/3.3/5.0---
 0Dh	WORD	entry count within directory
 0Fh	WORD	cluster number of start of parent directory
 11h  4 BYTEs	reserved
---OS/2 MVDM---
 00h	WORD	"OS2_BMP_handle"
 02h	WORD	"OS2_LastEnt"
 04h	DWORD	"OS2_Checksum"
 08h	BYTE	"OS2_usi_flag"
 09h	DWORD	used by DOS emulator for second pass for volume-label searches
 0Dh	WORD	(ret) "DOS_LastEnt" entry count within directory
 0Fh	BYTE	OS/2 Processed-FindFirst flag
		00h FindFirst processed by DOS
		42h FindFirst processed by OS/2
 10h  5 BYTEs	reserved for future use
---all versions, documented fields---
 15h	BYTE	attribute of file found
 16h	WORD	file time (see #01665 at AX=5700h)
 18h	WORD	file date (see #01666 at AX=5700h)
 1Ah	DWORD	file size
 1Eh 13 BYTEs	ASCIZ filename+extension
RBIL-> inter61b.zip-> INTERRUP.G

Code: Alles auswählen

--------D-214F-------------------------------
INT 21 - DOS 2+ - "FINDNEXT" - FIND NEXT MATCHING FILE
	AH = 4Fh
	Disk Transfer Area contains data block from previous FindFirst or
	  FindNext call
Return: CF clear if successful
	    Disk Transfer Area updated
	CF set on error
	    AX = error code (12h) (see #01680 at AH=59h/BX=0000h)
Notes:	under Novell DOS 7, if the FindFirst call (AH=4Eh) had CX=0088h, then
	  the next matching deleted file will be returned
	since the entire state of a FindFirst/FindNext sequence is contained
	  in the data block in the DTA, other disk operations such as renaming,
	  moving, deleting, or creating files can cause inaccurate directory
	  searches, such as finding the same file twice
BUG:	DR DOS 3.41 and 5.0 return the Directory attribute for the volume label
SeeAlso: AH=12h,AH=4Eh,AX=714Fh,AX=71A1h
Hier ist noch ein angefangenes Beispiel-Listing wo ich änlich wie der Norton-Commander, aber nicht nur 2 Verzeichniss-Ansichten , sonden 6 Spalten mit 6 verschiedenen Laufwerken gleichzeitig zur Anzeige bringen möchte.

Code: Alles auswählen

.MODEL SMALL
.386
.CODE
 ORG 100h
     mov     ax, 1112h     ; 8x8  Matrix 50 Zeilen
     xor     bl, bl
     int  10h
     mov     ax, @DATA     ; Daten-Segment bestimmen
     mov     ds, ax
     mov     ax, 0B800h    ; Bild-Segment bestimmen
     mov     es, ax
;═════════════════════════════════════════════════════════════════════════
;   Bildschirm loeschen
;═════════════════════════════════════════════════════════════════════════
     xor     di, di
     mov     cx, 9E8h
     mov    eax, 1B201B20h
     rep stosd
     mov     di, 1EA0h
     mov     cx, 28h
     mov    eax, 2B202B20h
     rep stosd
;═════════════════════════════════════════════════════════════════════════
;   Rahmen-malen
;═════════════════════════════════════════════════════════════════════════
     xor     di, di
     mov     al, 0C9h      ;  1 mal "╔" ausgeben
     stosw
     mov     cx, 27h
     mov    eax, 1BCD1BCDh ; 78 mal "═" ausgeben
     rep stosd
     mov     al, 0BBh      ;  1 mal "╗" ausgeben
     stosw
     mov     al, 0BAh      ; 47 mal "║" ausgeben
     mov     cx, 2Fh
P1:       stosb
     add     di, 9Dh
     stosw                 ; 47 mal "║" ausgeben
     loop P1
     mov     al, 0C8h      ;  1 mal "╚" ausgeben
     stosw
     mov     al, 0CDh      ; 78 mal "═" ausgeben
     mov     cl, 27h
     rep stosd
     mov     al, 0BCh      ;  1 mal "╝" ausgeben
     stosb
     mov     al, 0BAh      ; 47 mal "║" ausgeben
     mov     di, 0BAh
     mov     cx, 2Fh
P2:       stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     inc     di
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     add     di, 35h
     loop P2
     mov    eax, 1BC41BC4h ; 78 mal "─" ausgeben
     mov     di, 1CC2h
     mov     cl, 27h
     rep stosd
     mov     al, 0CBh      ;  5 mal "╦" ausgeben
     mov     di, 1Ah
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     inc     di
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     mov     al, 0CAh      ;  5 mal "╩" ausgeben
     mov     di, 1E1Ah
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     inc     di
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     mov     al, 0D7h      ; "Î" ausgeben
     mov     di, 1CDAh
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     inc     di
     stosb
     add     di, 19h
     stosb
     add     di, 19h
     stosb
     mov     al, 0C7h      ; "Ã" ausgeben
     mov     di, 1CC0h
     stosb
     mov     al, 0B6h      ; "Â" ausgeben
     add     di, 9Dh
     stosb
;═════════════════════════════════════════════════════════════════════════
;   LABEL des Laufwerks ausgeben
;═════════════════════════════════════════════════════════════════════════
     mov     dl, 2       ; Laufwerk setzen (0=A;1=B usw.)
     mov    ds:[LAUF], dl
LA:       mov     ah, 0Eh                    
     int   21h
;--------------------------------------
     mov     cx, 8       ; Attribute  LABEL
     call ERE            ; ersten Verzeichniss-Eintrag holen
     jc  DOS
               ;--------------------------------------
     call DITA           ; DTA holen
     mov     dl, LAUF
     sbb     dl, 2
               ;--------------------------------------
     push    ds
     push    es
     pop     ds
     mov     ax, 0B800h
     mov     es, ax
               ;--------------------------------------
     mov     di, 0A6h
     mov     ax, 1Ah
     mul     dl
     add     di, ax
     mov     ah, 1Eh     ; Farbe
     mov     cx, 1Eh     ; Zaehler
               ;--------------------------------------
ILES:     mov     al, ds:[bx] ; ASCII holen
     cmp     al, 0       ; Namens-Ende erreicht ?
     jz  FILEN
     cmp     al, 60h     ; Klein-Buchstaben ?
     jna KLE
     sbb     al, 20h     ; gross machen
KLE:      stosw
     inc     bx
     inc     cx
     cmp     cx, 2Bh     ; schon ganzer Name
     jnz ILES
FILEN:    pop     ds
;═════════════════════════════════════════════════════════════════════════
;   File-Tabelle anlegen
;═════════════════════════════════════════════════════════════════════════
     mov     cx, 21h     ; Attribut alle, ohne System/Hidden/Sub/Label
     call ERE            ; ersten Verzeichniss-Eintrag holen
     jc  DOS
               ;--------------------------------------
     call DITA           ; DTA holen = BX
     lea     bp, TAB     ; Zeiger auf Rett-Tabelle
     xor     si, si
               ;--------------------------------------
NEXT:     mov     bx, DTA     ; Zeiger holen
     mov     cx, 0Ch     ; Zaehler
LESE:     mov     al, es:[bx] ; ASCII holen
               ;--------------------------------------
     cmp     al, 0       ; Ende erreicht ?
     jz  FILEND
     cmp     al, "."     ; schon Punkt erreicht ?
     jnz FEN
               ;--------------------------------------
     add     bp, cx
     mov     cl, 4       ; nur noch 4 Zeichen
     sbb     bp, cx
     mov     al, 20h     ; Space
     jmp  GRO
               ;--------------------------------------
FEN:      cmp     al, 5Bh     ; Gross-Buchstaben ?
     jnb GRO
     cmp     al, 40h     ; Gross-Buchstaben ?
     jb  GRO
     add     al, 20h     ; klein machen
               ;--------------------------------------
GRO:      mov   ds:[bp], al   ; in Tabelle ablegen
     inc     bp
     inc     bx
     loop LESE                    
               ;--------------------------------------
FILEND:   inc     si
     add     bp, cx
     mov     cx, 21h     ; Attribute alle, ohne System/Hidden/Sub/Label
     call NEH            ; Naechsten Eintrag holen
     jnc NEXT
;═════════════════════════════════════════════════════════════════════════
     call ESORT
;═════════════════════════════════════════════════════════════════════════
     call NILOU          ; alle File-Namen eines Laufwerks ausgeben
;═════════════════════════════════════════════════════════════════════════
     call FTR            ; Tabellen-Bereich loeschen
;═════════════════════════════════════════════════════════════════════════
     call LFOUT          ; oben Ausgabe des Laufwerks Buchstaben
;═════════════════════════════════════════════════════════════════════════
     inc    BYTE PTR[LAUF]       ; Laufwerk erhoehen
     mov     dl, BYTE PTR[LAUF]
     cmp     dl, 5
     jnz LA
;═════════════════════════════════════════════════════════════════════════
;═════════════════════════════════════════════════════════════════════════
;═════════════════════════════════════════════════════════════════════════
;   unten Eingabezeile: Pfad/Laufwerk ausgeben
;═════════════════════════════════════════════════════════════════════════
     mov     dx, 3       ; Laufwerk setzen (0=A;1=B usw.)
     mov     ah, 0Eh                    
     int   21h                    
               ;--------------------------------------
     mov     ah, 19h     ; aktuelle Laufwerks-Nr. holen
     int   21h
     inc     al
               ;--------------------------------------
     lea     si, PFAD    ; Pfad holen
     mov     dl, al
     mov     ah, 47h
     int   21h
     jc  DOS
               ;--------------------------------------
     xor     cl, cl
     lea     bx, LFW
     add     bx, dx
     mov     al, [bx]    ; Laufwerks-Ascii holen
     mov     ah, 2Fh
     mov     di, 1EA0h
     stosw               ; Laufwerk
     mov     al, ":"     ; Doppelpunkt
     stosw
     mov     al, "\"     ; Backslash
SUCH0:    stosw
     lodsb               ; Pfad
     inc     cl
     cmp     al, 0
     jnz SUCH0
     mov     al, ">"     ; Backslash
     stosw
               ;--------------------------------------
     mov     dh, 31h     ; Coursor setzen
     mov     dl, 3
     add     dl, cl
     xor     bh, bh
     mov     ah, 2
     int   10h
;═════════════════════════════════════════════════════════════════════════
DOS:      mov     ax, 1
     int   16h
     mov     ax, 4C00h
     int   21h
;═════════════════════════════════════════════════════════════════════════
;═══════════════ S U B ═══════════════════════════════════════════════════
;═════════════════════════════════════════════════════════════════════════
ERE:      mov     ah, 4Eh     ; Ersten Verzeichniss-Eintrag holen
     xor     si, si      ; Anzahl der Namen              
     lea     dx, NAM     ; NAME DS:DX
     int   21h
     ret
;═════════════════════════════════════════════════════════════════════════
NEH:      mov     ah, 4Fh     ; Naechsten Eintrag holen
     lea     dx, NAM     ; NAME DS:DX
     int   21h
     ret
;═════════════════════════════════════════════════════════════════════════
DITA:     mov     ah, 2Fh     ; DTA holen
     int   21h           ;            OUT: ES:BX (Disk Tranfer Adress)
     add     bx, 1Eh     ; Zeiger auf Namen (DTA: 1E - 2A)
     mov    ds:[DTA], bx ; Zeiger retten
     ret
;═════════════════════════════════════════════════════════════════════════
;   sortierung der filenamen Extensionen nach dem Alphabeth
;═════════════════════════════════════════════════════════════════════════
ESORT:    xor     cx, cx
     mov     di, 09h
     mov     bp, di
ES0:      mov     al, BYTE PTR[TAB + di]
ES1:      add     bp, 0Ch
     inc     cx
     cmp     cx, si
     jz   ES2
     cmp     al, BYTE PTR[TAB + bp]
     ja   ES1
     mov     di, bp
     jmp  ES0
ES2:      

     ret
;═════════════════════════════════════════════════════════════════════════
;   alle File-Namen eines Laufwerks ausgeben
;═════════════════════════════════════════════════════════════════════════
NILOU:    mov     fs, si      ; Anzahl retten
     mov     ax, 0B800h
     mov     es, ax
     lea     si, TAB     ; Zeiger auf Tabelle
     mov     bp, fs
     mov     dh, 2       ; ZEILE 2 
               ;--------------------------------------
FILOUT:   mov     ax, 0A0h    ; max.Spalte
     mul     dh          ;   mal Zeile
     mov     di, ax
     add     di, 2
     mov     bl, LAUF  
     sbb     bl, 2
     mov     ax, 1Ah     ; Tab.
     mul     bl
     add     di, ax      ; nur dl dazu
               ;--------------------------------------
     mov     ah, 1Bh     ; Farbe
     mov     cx, 0Ch     ; laenge des File-Namens
NEFI:     lodsb               ; File-Namen ausgeben
     stosw
     loop NEFI
               ;--------------------------------------
     cmp     dh, 2Dh     ; schon letzte Zeile ?
     jz  FUT
     inc     dh
               ;--------------------------------------
     dec     bp          ; schon letztes File ?
     jnz  FILOUT
FUT:      ret
;═════════════════════════════════════════════════════════════════════════
;   Tabellen-Bereich loeschen
;═════════════════════════════════════════════════════════════════════════
FTR:      mov     ax, @DATA
     mov     es, ax
     lea     di, TAB
     mov     ax, 0Eh
     mov     si, fs
     mul     si
     shr     ax, 2
     mov     cx, ax
     mov    eax, 2020h
     rep stosd
     mov     ax, 0B800h
     mov     es, ax
     ret
;═════════════════════════════════════════════════════════════════════════
;   oben Ausgabe des Laufwerks Buchstaben
;═════════════════════════════════════════════════════════════════════════
LFOUT:    xor     dh, dh
     mov     dl, LAUF
     sbb     dl, 2
     mov     ax, 1Ah
     mul     dl
     mov     di, 8
     add     di, ax
     mov     ax, 1F20h
     stosw
     mov     dl, LAUF
     lea     bx, LFW
     add     bx, dx
     inc     bx
     mov     al, [bx]    ; Laufwerks-Ascii holen
     stosw
     mov     al, 3Ah
     stosw
     mov     al, 5Ch
     stosw
     mov     al, 20h
     stosw
     ret
;═════════════════════════════════════════════════════════════════════════
.DATA
LAUF   DB  2                             ; Dos-Laufwerk setzen dl=Laufwerk
NAM    DB  2Ah, 2Eh, 2Ah, 0              ; alle Files "*.*"
LFW    DB  "0ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; Tabelle der Laufwerks-Ascii
DTA    DW  0080h                         ; Offset der DTA
PFAD   DB  64 DUP (0)                    ; aktueller Pfad
TAB    DB  ?                             ; Tabelle der Namens-Eintraege
 org  4000h
TABS   DB  ?                       ; Tabelle der sortierten Namens-Eintraege
;═════════════════════════════════════════════════════════════════════════
 org  8000h
.STACK 20h
 END
Dirk
Antworten