DOS alatt fájlkezelés C++/Assembly

Sziasztok!

DOS-ra fejlesztett programhoz szeretnék egy fájl tallózót készíteni. A program C++-ban készül, assembly kód részletekkel
megtoldva és OpenWatcom fordítót használok. A fent említett fájl tallózó készítésénél akadtak problémáim, mivel nem igazán tudom hogyan lehet lekérdezni DOS alatt a meghajtókat, illetve mappa tartalmát listázni.... Eddig dos.h-ban, illetve neten az int 21h környékén keresgéltem, nem sok sikerrel.
Tudom hogy nem Un*x és még csak nem is Windows... Egy hobbi projekt ami egy régi számítógépre készül :)

Ha valaki tudna segíteni e témában, megköszönném :)

Hozzászólások

Megpróbáltam ezek alapján elindulni:


Function (AH) | Input | Output | Description
___________________________________________________________________________________________
0Eh | dl- drive number | al- number of logical drives | Set Default Drive: sets the DOS default drive to the specified value (0=A, 1=B, 2=C, etc.). Returns the number of logical drives in the system, although they may not be contiguous from 0-al.
___________________________________________________________________________________________
19H | | al- default drive number | Get Default Drive: Returns the current system default drive number (0=A, 1=B, 2=C, etc.).

Amivel próbálkoztam:


#include stdio.h

unsigned char GetDefaultDrive()
{
static unsigned char ret;
__asm
{
xor ax, ax
mov ah, 19h
int 21h
}
return ret;
}

static unsigned char ldrives;
void SetDefaultDrive(unsigned char drive)
{
__asm
{
xor ax, ax
xor dx, dx
mov ah, 1Eh
mov dl, drive
int 21h
mov ldrives, al
}
}

int main(int argc, char * argv[])
{
ldrives = 0;
SetDefaultDrive(1);
printf ("Default drive is: %d\r\n", GetDefaultDrive());
printf ("Number of drives: %d", ldrives);
getchar();
return 0;
}

Lehet valamit félreértelmeztem, de sajnos ez a kimenet WinXP, illetve
DOSBox alól futtatva is:


Default drive is: 0
ldrives: 0

Régi szép int21-es idők... Bár nekem csak TurboC++, meg tasm vagy épp masm jutott anno :-P

+1

Meg Ralph Brown-féle interrupt list. Nálam Turbo Pascal volt, először ASM betétekkel, majd tasm, végül BAPC (elvileg arpi_esp alkotta). Az x86 vírusok érdekeltek anno nagyon. Volt rá példa, hogy nem volt nálam rendszerlemez, ezért debug.exe -vel hatástalanítottam egy TSR vírus int 21h funkcióit (NOP-oltam), így újraindítás nélkül lehetett írtani. Régi szép idők! :)

Mai friss fejjel átnézve a tegnapi kódomat, kijavítva most már tökéletes a meghajtó listázás. Már csak a fájlok listázását kell megoldani, amihez köszönöm szépen a linkeket!

Végleges meghajtó listázó kód:

#include <stdio.h>

unsigned char GetDefaultDrive()
{
static unsigned char r;
__asm
{
xor ax, ax
mov ah, 19h
int 21h
mov r, al
}
return r;
}

void SetDefaultDrive(unsigned char drive)
{
__asm
{
xor ax, ax
xor dx, dx
mov ah, 0Eh
mov dl, drive
int 21h
}
}

int main(int argc, char * argv[])
{
unsigned int i;
unsigned char defDrive = GetDefaultDrive();
for (i=0;i<26;i++)
{
SetDefaultDrive(i);
if (GetDefaultDrive() == i) printf ("%c:\r\n", 65+i);
}
SetDefaultDrive(defDrive);
return 0;
}

Tudom hogy lehetne szebben is, mert megpörgeti a floppy meghajtót mikor vált, de nem jöttem rá hogyan lehetne másképp. A Norton Commander valószínűleg más taktikát használ erre.

Még egy kérdésem, hogy most pedig a fájl listázásnál akadtam el, azt merre fele keressem?
Itt kezdtem keresgélni:
http://www.techhelpmanual.com/8-directory_and_file_functions.html

Szerk: erre már kaptam választ az első hozzászólásban

elokerestem a programolo megazmsdos cimu Petho konyvet, ez alapjan ha jolvizualom, a dos_dsksel (0eh) segedelmevel beallitod a default driveot, aztan a dos_getdsk (19h) lekerdezed sikeres volt-e ?
szvsz a dos_gtcdir azaz a 47h fuggvennyel egyszeubb lehet, diszk sorszamot ott is lehet megadni, hibakod jon vissza, ha nemletezik a diszk.

----

47h Get Current Directory, DOS_GTCDIR

A kurrens directory lekérdezése - belépéskor DL-ben adjuk meg a kívánt lemezegység kódját, (0 - kurrens lemez, 1 - A: , 2 - B: stb. ), DS:SI-ben pedig egy 64 byte-nyi memóriablokk címét. A teljes "path" fogja ide beirni a redszer a lemezegység megadása valamint a bevezető és záró "\" karakterek nélkül.

Hibakódok AX-ben Carry=1 esetén:

0F - érvénytelen lemezkód

----

és tényleg volt, sikerült is
Már csak annyi, hogyan tudom a mappákat is listázni?

#include <iostream>
#include <dos.h>
using namespace std;

int main(int argc, char * argv[])
{
find_t f;
cout << "DOS Mappa listazas" << endl << __TIME__ << endl;
if (_dos_findfirst("C:\\*.*", 0, &f))
{
cerr << "A mappa ures" << endl;
return 1;
}
while (!_dos_findnext(&f))
{
cout << f.name << endl;
}
return 0;
}

xp alatt borland pascal 7.0

-------

Program teszt ;

uses crt;

var currdir : array[1..128] of byte;
hiba : byte ;

procedure getdir(drivenum: byte);

begin
hiba := 0;
asm
mov dl,drivenum
mov si, offset currdir
mov ah,47h
int 21h
jnc @kilep
mov [hiba],al
@kilep:
end ;
end ;

begin
clrscr;
getdir(1);
if hiba <> 0 then writeln('1. drive error kod :', hiba);
getdir(2);
if hiba <> 0 then writeln('2, drive error kod :', hiba);
getdir(3);
if hiba <> 0 then writeln('3. drive error kod :', hiba);
getdir(4);
if hiba <> 0 then writeln('4. drive error kod :', hiba);
end .

----------------

ez igy az 1 es 2 ertekre ( A: B: ) hozza a 0Fh 'nemletezo drive' hibakodot, critical ablak nem jelenik meg, a 3/4 ertekre nem problemazik.
a fejmozgatasrol floppy hianyaban nem tudok nyilatkozni.

kiprobaltam dos alatt, valoban dobja a hibat.
az almoskonyv szerint ha ilyen 'nincs lemez az egysegben' hiba van, a 24h interruptot hivja a dos.
az lehet a megfejtes, hogy a drivelekerdezes idejere a 24h interruptot sajat kezelore iranyitod, es visszakezbol adsz neki egy ignore (AL=0) vagy fail (AL=3) erteket.

az asm blokkon beluli iret nembiztos, hogy jo huzas, meg kellene nezni, az adott fordito milyen pre ( push bp, mov bp,sp , sub sp,x ; modernebbek enter x,y ) kodot tesz egy fuggvany belepeshez, es ehhez igazitani a kodot, kulonben rossz helyre ter vissza.
anno pascalban meg kellett adni, hogy az adott fuggveny egy interrupt hivassal van aktvizalva, akkor ugy kezelte.

>>> procedure valami ; interrupt ; <<<

ha-ha ms-dos. atirt 24h interrupt vektorral kiprobaltam, most arra ker, hogy csereljek lemezt a b meghajtoban :)
ugye egymeghajtoval is van copy a: b: lemezcserelgeteses modszerrel...
ha lesz idom elokaparok egy nc -t, az a gyanum, hogy a trukk annyi, hogy c: -tol kezdve kerdezi le a diszkeket, az 'a' es a 'b' meghajtot adottnak veszi.

Program teszt ;

uses crt,dos;

var currdir : array[1..128] of byte;
hiba : byte ;

procedure getdir(drivenum: byte);

begin
hiba := 0;
asm
mov dl,drivenum
mov si, offset currdir
mov ah,47h
int 21h
jnc @kilep
mov [hiba],al
@kilep:
end ;
end ;

var i : byte;
bioshwreport : word;

begin
clrscr;

asm
int 11h
mov [bioshwreport],ax
end ;

if ( bioshwreport and $0001 ) <> 0 then { van floppy ? }
begin
{ oke, 'a' egyseg tutti }
getdir(1);
write('a:');
if ( hiba = 0 ) then writeln('ok') else writeln('hiba');

{ a 6-7 bit adja meg a floppyk szamat. -1 }
{ de engem most kiserletileg csak a 'b:' erdekel }

if ( ( bioshwreport and $C0 ) <> 0 ) then
begin
getdir(2);
write('b:');
if ( hiba = 0 ) then writeln('ok') else writeln('hiba');
end ;

end ;

for i:= 3 to 26 do
begin
getdir(i);
write( char(64+i),':' );
if hiba = 0
then writeln('ok')
else writeln('hiba');
end ;

end .

ott az also ablakban az uzenet :
can't find unit - ilyet en sosem kaptam freepascallal sem, de ugytunik vagy nincsenek meg az unitok, vagy rossz helyre mutat a library path.
az options -> directories -> units alatt nezd meg mi van beallitva.
ugyanakkor javaslom a borland fordito beszerzeset, en azzal irtam, pascalkent teljesen kompatibilis az fp, viszont az asm betetet meg sosem probaltam.

Na Borland Pascal-al lefordítva már tökéletes :D
http://185.112.156.62/floppy.jpg
Úgyhogy szerintem minden megvan amit kértem! (Mondjuk már azon jár a fejem, hogy ezt azzal bővíteni hogy felismerje a meghajtó típusát, kötetcímke..., de ezt majd megoldom) Majd a végeredmény kódból teszek ki ide, hátha nem csak én leszek az egyetlen aki ilyen hobbi program írásába fog.
Mindenkinek nagyon szépen köszönöm a segítségét!

Off: ez a topic csúnya dolog volt, elrontott, mert előszedte a régi emlékeket, és újra kedvet kaptam az ilyenekhez :-D

Win 3.11 programozással elég sokat lehetett szívni, meg tanulni is (autodidakta módon csináltam). És volt a Turbo Debugger for Windows, ami a világért nem akart együttműködni a számítógép videokártyájával (konzolos módot használt, de Windows alkalmazás volt, elég furcsa kombináció). Ekkor kezdtem alternatív hibakeresési módszereket tanulni.

Meg a toolhelp.dll-lel lehetett vicces dolgokat csinálni, pl. alkalmazás kilövését elkapni, meg ilyenek.

Assembly helyett: "Borland C" és "Turbo C" szavak a keresés kifejezésében a Google felé és remélhetőleg nem POSIX megoldásokat hoz fel.

Egy tipp a directory listázásra:
http://www.softwareandfinance.com/forums/index.php?topic=504.0

Továbbá:
https://books.google.hu/books?id=1S6jBQAAQBAJ&pg=PA354#v=onepage&q&f=fa…

354. oldaltól. setdisk - ahogy elnézem, végig kell próbálni [A-Z] között.

... de régen volt (20 éve), amikor még DOS-t programoztam.