DosQueryPathInfo() in C++

(DE) Projekte für OS/2, eCS und ArcaOS
(EN) OS/2, eCS and ArcaOS related projects
Antworten
Benutzeravatar
LotharS
Beiträge: 968
Registriert: So 29. Dez 2013, 20:07
Wohnort: Düsseldorf
Kontaktdaten:

DosQueryPathInfo() in C++

Beitrag von LotharS »

Bitte um große Nachsicht, ich versuche gerade durch C++ zu stolpern. Meine letzten "Schritte" darin sind immerhin 20 Jahre her... An "Hello World" bin ich zwar deutlich vorbei, und eigentlich reizen mich ja auch ernstere Aufgaben. Zum Beispiel diese:

Ich möchte (innerhalb einer Anwendung) u.a. die Größe einer Datei bestimmen. Dazu finde ich in der Toolkit-Hilfe "addendum.inf" ein Beispiel zu DosQueryPathInfo(). Hab's ausprobiert mit dem VisualAge-3.08-Compiler und tut.
Sodann leicht modifiziert, formal zunächst so dass es mit "C++" compiliert wird (auch ok) , und anschließend...
(1) an "FILESTATUS3" ein "L" angehängt und passend dazu "FIL_STANDARDL". Passt ebenfalls.
(2) zwei Zeilen "cout << ..." eingefügt: Der Compiler meldet zur zweiten Zeile "Call does not match any argument list for "ostream::operator<<" im Falle "...L", nicht aber ohne "...L". Suspekt... :?:

Habe schon durchgegoogelt, aber da unterhalten sich anscheinend nur fortgeschrittene Experten. Ich dagegen bräuchte eine Erklärung (oder Fundstelle) als sei ich Fünf... ;)

Zusatzfrage: das Resultat Dateigröße (".cbFile") usw. möchte ich ja eigentlich nicht auf der Konsole anzeigen, sondern weiterreichen an eine verarbeitende Routine. Auch der Pfadname nicht etwa eingetippt, sondern von einer aufrufenden Routine variabel übergeben. Worauf muss ich dabei achten? Oder gibt es etwas viel Einfacheres? Danke im voraus :)

Mein modifizierter Code-Sample hier (vgl.Toolkit- "addendum.inf"):

Code: Alles auswählen

 #define INCL_DOSFILEMGR   /* File Manager values */
 #define INCL_DOSERRORS    /* DOS error values    */
 #include <os2.h>
 #include <stdio.h>
 #include <stdlib.h>
#include <iostream.h>      /* -- eingefügt -- */

 int main(VOID) {
 PCSZ  path       = "C:\\config.sys";  /* File to manipulate   */
 FILESTATUS3L  fs = {{0}};           /* Buffer for file information */
 ULONG  ulBufSize = sizeof(FILESTATUS3L);   /* Size of above buffer */
 APIRET rc        = NO_ERROR;        /* Return code                 */

    rc = DosQueryPathInfo(path, /* Path and name of file   */
                FIL_STANDARDL,  /* Request standard (Level 11) info */
                &fs,    /* Buffer for file information     */
                ulBufSize);     /* Size of buffer          */
    if (rc != NO_ERROR) {
        printf("DosQueryPathInfo error: return code = %u\n", rc);
        return 1;
    }

  /* -- eingefügt --  */
  cout << path << endl;       /* ok */
  cout << fs.cbFile << endl;  /* ok ohne "..L", error mit "..L" */

    printf("%s ---  File size: %u bytes\n",path, fs.cbFile);
    printf("Last updated: %d.%d.%d; %d:%2.2d\n",
            fs.fdateLastWrite.day,          /* Day              */
            fs.fdateLastWrite.month,        /* Month            */
            (fs.fdateLastWrite.year+1980L), /* Years since 1980 */
            fs.ftimeLastWrite.hours,        /* Hours            */
            fs.ftimeLastWrite.minutes);     /* Minutes          */

  return NO_ERROR;
}
ehemaliger
Beiträge: 102
Registriert: Mi 22. Nov 2017, 23:46

Beitrag von ehemaliger »

Würde vermuten, daß dieser Steinzeit-Compiler keine 64bit-Datentypen beherrscht und 'LONGLONG' daher als struct bestehen aus je 32bit Low- und Highteil deklariert ist.
Benutzeravatar
aschn
Beiträge: 1363
Registriert: Mi 25. Dez 2013, 22:47

Beitrag von aschn »

Das passt. os2def.h:

Code: Alles auswählen

    typedef struct _LONGLONG {  /* LONGLONG */
        ULONG ulLo;
        LONG ulHi;
    }LONGLONG;
Andreas Schnellbacher
Andi B.
Beiträge: 742
Registriert: Di 24. Dez 2013, 16:40
Kontaktdaten:

Beitrag von Andi B. »

Das mit LONGLONG hat mich auch schon mal genervt. Irgendwann war auch mal ein "#define INCL_LONGLONG" vorm "#include <os2.h> notwendig/sinnvoll. Ich denke der vac3.08 konnte das nur mit der struct welche aschn schon gepostet hat, ab dem 3.65 geht LONGLONG auch direkt. Rein interessehalber, welches Toolkit verwendest du? Das mit 3.08 mitgelieferte, oder das os2tk45?
Benutzeravatar
LotharS
Beiträge: 968
Registriert: So 29. Dez 2013, 20:07
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von LotharS »

ehemaliger hat geschrieben: Mi 22. Jul 2020, 17:23 Würde vermuten, daß dieser Steinzeit-Compiler keine 64bit-Datentypen beherrscht und 'LONGLONG' daher als struct bestehen aus je 32bit Low- und Highteil deklariert ist.
Der Steinzeit-icc nimmt sogar FILESTATUS4L mit passendem FIL_ Level, und liefert auch Größen > 2GB, printf() spielt sauber mit. Was bisher allein blockiert, ist "cout". Ich wüßte auch nicht was die unter dem "DIR"-Command auch anders tun und (erst) neuere XWP's ebenfalls...
Benutzeravatar
LotharS
Beiträge: 968
Registriert: So 29. Dez 2013, 20:07
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von LotharS »

Andi B. hat geschrieben: Mi 22. Jul 2020, 18:24 Rein interessehalber, welches Toolkit verwendest du? Das mit 3.08 mitgelieferte, oder das os2tk45?
Aktiv ist neuestes os2tk45 aus ANPM. Das ältere aus der eCS-CD2 ist nur formal installiert wegen der WPS-Icons, hängt aber in der config.sys jeweils ganz hinten. Die 'Working Dir' aus all den Icons zu putzen war stupide aber begrenzte Handarbeit, ein Script für die Icons wäre ja mal ganz nett ...

Danke für die Tipps, aber's HomeOffice hat jetzt zu :roll:
ehemaliger
Beiträge: 102
Registriert: Mi 22. Nov 2017, 23:46

Beitrag von ehemaliger »

LotharS hat geschrieben: Mi 22. Jul 2020, 19:19Der Steinzeit-icc nimmt sogar FILESTATUS4L mit passendem FIL_ Level, und liefert auch Größen > 2GB, printf() spielt sauber mit.
Du hast sicherlich den Formatspecifier von "%u" in "%llu" geändert und probiert, ob es mit Dateien > 4GB auch noch "funktioniert". Oder? Und die Zusammenfassung der Ausgabe von Pfad, Größe und Datum in einer einzigen printf-Anweisung liefert auch ein korrektes Ergebnis. Wenn das klappt, dann kann der Compiler mehr als ich in Erinnerung hatte...
Benutzeravatar
LotharS
Beiträge: 968
Registriert: So 29. Dez 2013, 20:07
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von LotharS »

aschn hat geschrieben: Mi 22. Jul 2020, 17:45 Das passt. os2def.h:

Code: Alles auswählen

    typedef struct _LONGLONG {  /* LONGLONG */
        ULONG ulLo;
        LONG ulHi;
    }LONGLONG;
Danke für den "Bringer" :D :

Code: Alles auswählen

  cout << "oben:  " << fs.cbFile.ulHi << endl;
  cout << "unten: " << fs.cbFile.ulLo << endl;
Immerhin funktionierte das "einfache" printf mit "%u" und cbFile > 2GB komplett. Hatte allerdings nur bescheidene < 4GB zur Hand ;)
erdmann
Beiträge: 594
Registriert: Mo 4. Jan 2016, 14:36

Beitrag von erdmann »

Hier ist eigentlich schon soweit alles gesagt: VAC 3.08 beherrscht nur 32-bit integer, VAC 3.65 versteht auch 64-bit integer.
Für den VAC 3.65 compiler muss man die Header mit #define INCL_LONGLONG einbinden damit er NICHT die Hilfsdatenstruktur nimmt, welche aus zwei 32-bit integer ein 64-bit integer "zusammenstückelt" sondern die neuen 64-bit integer Datentypen benutzt (long long, unsigned long long).

Damit man nun für den VAC 3.08 sinnvoll ein unsigned 64-bit integer ausgeben kann ist es also nötig, den Wert als DOUBLE Wert umzurechnen, welches durch folgende Rechnung schnell erledigt ist:
double temp = 4294967296.0 * fs.cbFile.ulHi + 1.0 * fs.cbFile.ulLo;
cout << "Size" << temp << endl;

"cout" ist entsprechend überladen, dass es auch double sowie float Zahlen formatieren kann.

Für signed integer ist allerdings Vorsicht geboten. Da wird die Umwandlung komplizierter.
ehemaliger
Beiträge: 102
Registriert: Mi 22. Nov 2017, 23:46

Beitrag von ehemaliger »

LotharS hat geschrieben: Do 23. Jul 2020, 11:05Immerhin funktionierte das "einfache" printf mit "%u" und cbFile > 2GB komplett. Hatte allerdings nur bescheidene < 4GB zur Hand ;)
Nur scheinbar... Mehr als 4Gb wird nicht gehen und

Code: Alles auswählen

printf("%s ---  File size: %u %s\n",path, fs.cbFile, "bytes");
wird entweder abstürzen oder etwas Unerwartetes ausgeben :evil:

Das Verhalten ist übrigens nicht unüblich: Während C++ häufig zu lautstarkem Meckern tendiert, schießt man sich mit C deutlich leichter in den Fuß...
Antworten