root/trunk/txlib/txfsys.c

Revision 10, 41.1 kB (checked in by jvw, 3 years ago)

Fix FileDialog? trap, other minor updates

Line 
1//
2//                     TxWin, Textmode Windowing Library
3//
4//   Original code Copyright (c) 1995-2005 Fsys Software and Jan van Wijk
5//
6// ==========================================================================
7//
8// This file contains Original Code and/or Modifications of Original Code as
9// defined in and that are subject to the GNU Lesser General Public License.
10// You may not use this file except in compliance with the License.
11// BY USING THIS FILE YOU AGREE TO ALL TERMS AND CONDITIONS OF THE LICENSE.
12// A copy of the License is provided with the Original Code and Modifications,
13// and is also available at http://www.dfsee.com/txwin/lgpl.htm
14//
15// This library is free software; you can redistribute it and/or modify
16// it under the terms of the GNU Lesser General Public License as published
17// by the Free Software Foundation; either version 2.1 of the License,
18// or (at your option) any later version.
19//
20// This library is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23// See the GNU Lesser General Public License for more details.
24//
25// You should have received a copy of the GNU Lesser General Public License
26// along with this library; (lgpl.htm) if not, write to the Free Software
27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28//
29// Questions on TxWin licensing can be directed to: txwin@fsys.nl
30//
31// ==========================================================================
32//
33// TxLib filesystem functions, base section
34//
35
36#include <txlib.h>                              // TxLib interface
37#include <txwpriv.h>                            // private window interface
38
39#include <sys/stat.h>                           // for low level stuff
40
41
42#if   defined (WIN32)
43#elif defined (DOS32)
44
45#define DRIVETYPE_REMOTE  0x1000                // BIT 12 from Ioctl 4409 dx
46#define DRIVETYPE_RAMDRV  0x0800                // BIT 11 from Ioctl 4409 dx
47
48#elif defined (LINUX)
49
50#define BLKGETSIZE        0x1260
51#define BLKSSZGET         0x1268
52
53#define ROOT_DEVICE       "/dev/root"
54
55// Translate root-devicename to disk-partition device name using cached /etc/fstab info
56static BOOL TxLinuxRootDevice                   // RET   rootdevice translated
57(
58   char               *devname,                 // IN    Line with a device-name
59   char               *root                     // OUT   Real root-device name
60);
61
62#else
63
64#define TXFSDC_BLOCKR         0x00              // block device removable
65#define TXFSDC_GETBPB         0x00              // get device bpb info
66
67#define TXFSDC_UNLOCK         0x00              // unlock logical drive
68#define TXFSDC_LOCK           0x01              // lock logical drive
69#define TXFSDC_EJECT          0x02              // eject removable
70#define TXFSDC_LOAD           0x03              // load removable
71
72typedef struct drivecmd
73{
74   BYTE                cmd;                     // 0=unlock 1=lock 2=eject
75   BYTE                drv;                     // 0=A, 1=B 2=C ...
76} DRIVECMD;                                     // end of struct "drivecmd"
77
78#define TXFSBPB_REMOVABLE     0x08              // BPB attribute for removable
79
80typedef struct drivebpb
81{
82   TXFS_EBPB           ebpb;                    // extended BPB
83   BYTE                reserved[6];
84   USHORT              cyls;
85   BYTE                type;
86   USHORT              attributes;              // device attributes
87   BYTE                fill[6];                 // documented for IOCtl
88} DRIVEBPB;                                     // end of struct "drivebpb"
89
90#endif
91
92
93/*****************************************************************************/
94// Build string with present volumes, optional FLOPPY and LAN drives included
95/*****************************************************************************/
96int TxFsVolumes                                 // RET   nr of drives listed
97(
98   ULONG               flags,                   // IN    FLOPPY/LAN/CD select
99   char               *vols                     // OUT   Present volumes
100)
101{
102   #if   defined (WIN32)
103   #elif defined (DOS32)
104      union  REGS      regs;
105      char            *ep;
106   #elif defined (LINUX)
107      //- to be refined
108   #else
109      ULONG            current;
110   #endif
111   USHORT              first = 2;               // default start at C:
112   USHORT              ml;
113   ULONG               drivemap = 0;
114   TXTM                drive;
115
116   ENTER();
117   TxFsAutoFailCriticalErrors( TRUE);           // avoid Not-ready pop-ups
118
119   if (flags & TXFSV_FLOP)                      // check floppies too
120   {
121      #if defined (DOS32)
122         ep = getenv( "FLOPPYDR");              // DFSee bootable CD/diskette ?
123         if (ep && (!strnicmp( ep, "B:", 2)))   // Booted from FSYS boot CDROM
124         {                                      // bootimage is A: - VERY SLOW!
125            first = 1;                          // so start at B:
126         }
127         else                                   // in all other cases
128         {                                      // start at diskette A:
129            first = 0;
130         }
131      #else
132         first = 0;
133      #endif
134   }
135
136   #if   defined (WIN32)
137      drivemap = GetLogicalDrives();
138   #elif defined (DOS32)
139      for (ml = first; ml < 26; ml++)           // drives A/B/C to Z
140      {
141         TxxClearReg( regs);
142         regs.h.al = 0x09;                      // block device, remote
143         regs.h.bl = (BYTE) (ml+1);             // 1=A, 2=B etc
144         TxxDosInt21( regs, TXDX_DOS_IOCTL);
145         if (regs.x.cflag == 0)                 // drive exists
146         {
147            //- to be refined, might use bit 12 (remote) as LAN indicator
148            //- and perhaps the MSCDEX calls for CDROM filtering
149
150            TRACES(( "Block device drivetype: 0x%4.4lx for drive: %c\n",
151                      TXWORD.dx, (char) (ml + 'A')));
152            drivemap |= (1 << ml);
153
154            // TRHEXS( 70, &gpar, sizeof(TXFS_GPARM), "TXFS_GPARM");
155         }
156      }
157   #elif defined (LINUX)
158      //- to be refined
159   #else
160      DosQCurDisk( &current, &drivemap);
161   #endif
162   strcpy( vols, "");
163   for (ml = first; ml < 26; ml++)              // drives A/B/C to Z
164   {
165      if (drivemap & (1 << ml))
166      {
167         TXTT       fstype;
168
169         sprintf(drive, "%c:", 'A' + ml);
170         if (TxFsType( drive, fstype, NULL))
171         {
172            BOOL       removable = TxFsIsRemovable( drive);
173            BOOL       incl = TRUE;
174
175            //- Note, connected Win-NT drives use the REAL FS-name like NTFS!
176            if     ((strnicmp( fstype, "LAN",    3) == 0) || //- OS/2 LAN drives
177                    (strnicmp( fstype, "REMOTE", 5) == 0)  ) //- NT disconnected
178            {                                                //- DOS REMOTE
179               incl = (flags & TXFSV_LAN);
180            }
181            else if (strnicmp( fstype, "CD", 2) == 0) // OS2:CDFS, DOS/WIN:CDROM
182            {
183               removable = TRUE;                // overrule for any CDROM
184               incl      = (flags & TXFSV_CD);
185            }
186            if ((flags & TXFSV_REM) && (removable == FALSE))
187            {
188               incl = FALSE;                    // just want removables ...
189            }
190            if (incl)
191            {
192               drive[1] = 0;                    // clip to just the letter
193               strcat( vols, drive);            // and add to volume-list
194            }
195         }
196      }
197   }
198   TxFsAutoFailCriticalErrors( FALSE);          // enable criterror handler
199   TRACES(("Volumes: '%s'\n", vols));
200   RETURN(strlen( vols));
201}                                               // end 'TxFsVolumes'
202/*---------------------------------------------------------------------------*/
203
204
205/*****************************************************************************/
206// Get volumelabel for specified driveletter, or -not-ready- if not accessible
207/*****************************************************************************/
208char *TxFsVolumeLabel                           // RET   label or "-not-ready-"
209(
210   char               *drive,                   // IN    Drive specification
211   char               *label                    // INOUT Label string (min 12)
212)
213{
214   #if   defined (WIN32)
215      TXTS             DriveRoot;
216      ULONG            ulMaxCompLen;
217      ULONG            ulFsFlags;
218      TXTS             fsname;
219   #elif defined (DOS32)
220      union  REGS      regs;
221      struct SREGS     sreg;
222      TXDX_RMINFO      txdx_rmi;
223      char            *fn;
224      char            *dta;
225   #elif defined (LINUX)
226      //- to be refined
227   #else
228      FSINFO           fsi;
229   #endif
230
231   ENTER();
232
233   strcpy( label, TXFS_NOTREADY);
234   #if   defined (WIN32)
235      sprintf(DriveRoot, "%c:\\", drive[0]);
236      if (!GetVolumeInformation( DriveRoot,
237                                 label,  TXMAXTS,
238                                 NULL, &ulMaxCompLen, &ulFsFlags,
239                                 fsname, TXMAXTS))
240      {
241         TRACES(("Get failed, label: '%s' error: %lu\n", label, GetLastError()));
242      }
243   #elif defined (DOS32)
244      if ((txwa->dpmi1 != NULL) && (txwa->dpmi2 != NULL))
245      {
246         memset( txwa->dpmi1, 0, 512);
247         memset( txwa->dpmi2, 0, 512);
248         fn    = txwa->dpmi1;                   // DPMI compatible spec
249         dta   = txwa->dpmi2;                   // DPMI compatible DTA
250
251         sprintf( fn, "%c:\\*.*", drive[0]);    // DPMI comp drive-spec
252
253         //- first DOS-int, 211A = Set DTA
254         memset( &regs,  0, sizeof(regs));
255         memset( &sreg,  0, sizeof(sreg));
256
257         memset( &txdx_rmi, 0, sizeof(txdx_rmi));
258         txdx_rmi.eax = 0x1A00;                 // Set DTA address AH=1A
259         txdx_rmi.ds  = txDpmiSegment(dta);     // in  DTA   (ds:dx, dx=0)
260
261         TRHEXS( 100,  &txdx_rmi,  sizeof(txdx_rmi), "txdx_rmi");
262
263         regs.w.ax    = TXDX_DPMI_RMINT;        // simulate realmode INT
264         regs.h.bl    = TXDX_DOS;               // DOS interrupt 21
265         regs.x.edi   = FP_OFF( &txdx_rmi);     // real mode register struct
266         sreg.es      = FP_SEG( &txdx_rmi);
267
268         txDpmiCall( &regs, &sreg);
269
270         TRACES(("regs.x.cflag:%4.4hx  ax:%4.4hx\n", regs.x.cflag, TXWORD.ax));
271
272         if (regs.x.cflag == 0)                 // DTA is set now
273         {
274            //- second DOS-int, 214E = FindFirst
275            memset( &regs,  0, sizeof(regs));
276            memset( &sreg,  0, sizeof(sreg));
277
278            memset( &txdx_rmi, 0, sizeof(txdx_rmi));
279            txdx_rmi.eax = 0x4E00;              // FindFirst       AH=4E
280            txdx_rmi.ecx = FATTR_LABEL;         // in  attribute
281            txdx_rmi.ds  = txDpmiSegment(fn);   // in  spec  (ds:dx, dx=0)
282
283            TRHEXS( 100,  &txdx_rmi,  sizeof(txdx_rmi), "txdx_rmi");
284
285            regs.w.ax    = TXDX_DPMI_RMINT;     // simulate realmode INT
286            regs.h.bl    = TXDX_DOS;            // DOS interrupt 21
287            regs.x.edi   = FP_OFF( &txdx_rmi);  // real mode register struct
288            sreg.es      = FP_SEG( &txdx_rmi);
289
290            txDpmiCall( &regs, &sreg);
291
292            TRHEXS( 100,  txwa->dpmi2,  512, "dpmi2 (DTA)");
293            TRACES(("regs.x.cflag:%4.4hx  ax:%4.4hx\n", regs.x.cflag, TXWORD.ax));
294
295            if (regs.x.cflag == 0)
296            {
297               strcpy( label, dta + 0x1e);      // label OUT
298            }
299         }
300      }
301   #elif defined (LINUX)
302      //- to be refined
303   #else
304      if (DosQueryFSInfo( *drive - 'A' +1, FSIL_VOLSER,
305                          &fsi, sizeof(FSINFO)) == NO_ERROR)
306      {
307         strcpy( label, fsi.vol.szVolLabel);
308      }
309   #endif
310   TRACES(("label: '%s'\n", label));
311   RETURN( label);
312}                                               // end 'TxFsVolumeLabel'
313/*---------------------------------------------------------------------------*/
314
315
316/*****************************************************************************/
317// Show volume/filesystem info for all registred drive-letters
318/*****************************************************************************/
319void TxFsDrivemap
320(
321   char               *lead,                    // IN    Lead text, max 3 chars
322   ULONG               flags                    // IN    FLOPPY/LAN/CD select
323)
324{
325   #if defined (LINUX)
326      FILE            *mnt;
327   #else
328      TXTT             volumes;
329   #endif
330   TXLN                line;
331   char               *s;
332
333   ENTER();
334
335   #if defined (LINUX)
336      if ((mnt = fopen( "/proc/mounts", "rb")) != NULL)
337      {
338         while (!feof(mnt) && !ferror(mnt))
339         {
340            if (fgets( line, TXMAXLN, mnt) != NULL)
341            {
342               if (strnicmp( line, "/dev/", 5) == 0)
343               {
344                  //- to be refined, honnor FLOPY/LAN/CD flags ?
345                  //- could do additional tests here ...
346
347                  if ((s = strchr( line, ' ')) != NULL)
348                  {
349                     *s = '\0';
350                     TxFsShow( lead, line);
351                  }
352               }
353            }
354         }
355         fclose( mnt);
356      }
357   #else
358      TxFsVolumes( flags, volumes);             // get available volumes
359      for (s = volumes; *s && !TxAbort(); s++)  // walk all volume letters
360      {
361         sprintf( line, "%c:", *s);
362         TxFsShow( lead, line);
363      }
364   #endif
365   VRETURN();
366}                                               // end 'TxFsDrivemap'
367/*---------------------------------------------------------------------------*/
368
369
370/*****************************************************************************/
371// Show volume/filesystem info on a single output line using TxPrint
372/*****************************************************************************/
373ULONG TxFsShow
374(
375   char               *lead,                    // IN    Lead text, max 3 chars
376   char               *drive                    // IN    Drive specification
377)
378{
379   ULONG               rc = TX_INVALID_DRIVE;
380   ULONG               frees;                   // Free sectors
381   ULONG               total;                   // Total sectors
382   USHORT              bps;                     // Sectorsize
383   BOOL                fType = FALSE;
384   TXTM                text;
385   TXTM                detail;
386   TXTT                leader;
387   #if defined (LINUX)
388      TXTM             device;
389   #endif
390
391   ENTER();
392
393   strcpy( leader, lead);                       // optional lead fragment
394   #if defined (LINUX)
395      strcat( leader, "Mounted device");
396   #else
397      if (TxFsIsRemovable( drive))
398      {
399         strcat( leader, "RemovableDrive");
400      }
401      else
402      {
403         strcat( leader, "Volume info on");
404      }
405   #endif
406
407   TxFsAutoFailCriticalErrors( TRUE);           // avoid Not-ready pop-ups
408   #ifndef LINUX
409   if (isupper(drive[0]))
410   #endif
411   {
412      fType = TxFsType( drive, text, detail);
413      TxStrip( text, text, 0, ' ');             // strip spaces from FS-name
414      if (strcmp(text, "UNKNOWN") != 0)
415      {
416         strupr( text);                         // uppercase for readability
417         rc = TxFsSpace(drive, &frees, &total, &bps);
418      }
419   }
420   #if defined (LINUX)
421      if (rc == NO_ERROR)
422      {
423         strcpy( device, drive);
424         TxLinuxRootDevice(drive, device);      // translate root device
425         TxPrint("%-18.18s: %s%-15.15s%s Size% 9.1lf MiB, fs: %s%s%s  %s%s\n",
426                  leader, CBG, device, CNN,
427                  (total == 0) ? 0 : TXS2MB(total,  bps),
428                  CBM, text, CBY, detail, CNN);
429      }
430      else
431      {
432         TxPrint("%-18.18s: %s%-15.15s%s is not accessible, fs: %s%s%s\n",
433                  leader, CBG, drive, CNN, CBM, (fType) ? text : "-", CNN);
434      }
435   #else
436      if (rc == NO_ERROR)
437      {
438         TxPrint("%-18.18s: %s%c:%s Free% 9.1lf MiB of% 9.1lf MiB, fs: %s%s%s  %s%s\n",
439                  leader, CBG, drive[0], CNN,
440                  (frees == 0) ? 0 : TXS2MB(frees,  bps),
441                  (total == 0) ? 0 : TXS2MB(total,  bps),
442                  CBM, text, CBY, detail, CNN);
443      }
444      else
445      {
446         TxPrint("%-18.18s: %s%s%s           Not ready, no size info, fs: %s%s%s\n",
447                  leader, CBG, drive, CNN, CBM, (fType) ? text : "-", CNN);
448      }
449   #endif
450   TxFsAutoFailCriticalErrors( FALSE);          // enable criterror handler
451   RETURN (rc);
452}                                               // end 'TxFsShow'
453/*---------------------------------------------------------------------------*/
454
455
456#if defined (USEWINDOWING)
457/*****************************************************************************/
458// Build selection-list with volume/FS info for drive-letters or Linux-devices
459/*****************************************************************************/
460TXSELIST *TxFsDriveSelist                       // RET   selection list or NULL
461(
462   ULONG               flags,                   // IN    include FLOP/LAN/CDROM
463   BOOL                flop                     // IN    runtime floppy test
464)                                               //       (A: = 0, C: = 2 etc)
465{
466   TXSELIST           *list  = NULL;            // total list
467   TXS_ITEM           *item;                    // single item
468   ULONG               entries = 0;             // entries in list
469   int                 i;
470   #if defined (LINUX)
471      FILE            *mnt;
472      TXLN             line;
473      TXTM             device;
474      TXTM             mount;
475      TXTM             fsys;
476      TXTM             rest;
477   #else
478      TXTM             volumes;
479      char             curdrive;
480      char            *s;
481      char            *startvolume = volumes;
482   #endif
483
484   ENTER();
485
486   #if defined (LINUX)
487      if ((mnt = fopen( "/proc/mounts", "rb")) != NULL)
488      {
489         while (!feof(mnt) && !ferror(mnt))
490         {
491            if (fgets( line, TXMAXLN, mnt) != NULL)
492            {
493               //- to be refined, honor exclude-floppy and LAN flags ?
494               if (strnicmp( line, "/dev/", 5) == 0)
495               {
496                  entries++;                    // count valid device names
497               }
498            }
499         }
500         if (TxSelCreate( entries, entries, entries,
501                          TXS_AS_NOSTATIC, FALSE, NULL, &list) == NO_ERROR)
502         {
503            list->astatus = TXS_AS_NOSTATIC;    // all dynamic allocated
504
505            fseek( mnt, 0, SEEK_SET);           // rewind to start of file
506            for (i = 0; (i < entries) && !feof(mnt) && !ferror(mnt);)
507            {
508               if (fgets( line, TXMAXLN, mnt) != NULL)
509               {
510                  if (strnicmp( line, "/dev/", 5) == 0)
511                  {
512                     if ((item  = TxAlloc( 1, sizeof(TXS_ITEM))) != NULL)
513                     {
514                        list->count    = i +1;  // actual item count
515                        list->items[i] = item;  // attach item to list
516
517                        if (((item->text = TxAlloc( 1, TXMAXTM)) != NULL) &&
518                            ((item->desc = TxAlloc( 1, TXMAXLN)) != NULL)  )
519                        {
520                           item->value  = TXDID_MAX +  i;
521                           item->helpid = TXWH_USE_WIN_HELP; // from list-window itself
522
523                           item->index  = 0;    // no quick-select
524
525                           line[ TXMAXTM -1] = 0;
526
527                           sscanf( line, "%s %s %s %s", device, mount, fsys, rest);
528                           TxLinuxRootDevice( line, device); // translate root device
529                           rest[ 2] = 0;
530                           strupr( rest);
531
532                           sprintf( item->text, "%-15s %s", device, fsys);
533                           sprintf( item->desc, "%-8.8s %-15.15s mounted %s at: %-35s",
534                                                 fsys, device, rest, mount);
535
536                           TRACES(("text: %d '%s'\n", strlen(item->text), item->text));
537                           TRACES(("desc: %d '%s'\n", strlen(item->desc), item->desc));
538                        }
539                     }
540                     i++;                       // to next entry
541                  }
542               }
543            }
544         }
545         fclose( mnt);
546      }
547   #else
548      getcwd( volumes, TXMAXTM);                // get current drive/directory
549      curdrive = toupper(volumes[0]);           // keep current driveletter
550
551      TxFsVolumes( flags, volumes);             // get available volumes
552
553      #if defined (DOS32)
554         if (TxPhysDisketteDrives() == 1)       // just one drive really there
555         {
556            if (strnicmp( volumes, "AB", 2) == 0) // A and B are listed
557            {
558               startvolume++;                   // quick hack to remove 'B:'
559               startvolume[0] = 'A';
560            }
561         }
562      #endif
563      if ((entries = strlen(startvolume)) != 0)
564      {
565         if (TxSelCreate( entries, entries, entries,
566                          TXS_AS_NOSTATIC, FALSE, NULL, &list) == NO_ERROR)
567         {
568            list->astatus = TXS_AS_NOSTATIC;    // all dynamic allocated
569
570            for (i = 0, s = startvolume; i < entries; i++, s++) // walk all volumes
571            {
572               if ((item  = TxAlloc( 1, sizeof(TXS_ITEM))) != NULL)
573               {
574                  list->count    = i +1;        // actual item count
575                  list->items[i] = item;        // attach item to list
576
577                  if (((item->text = TxAlloc( 1, TXMAXTT)) != NULL) &&
578                      ((item->desc = TxAlloc( 1, TXMAXLN)) != NULL)  )
579                  {
580                     char    drive[3];
581
582                     sprintf(drive, "%c:", *s);
583
584                     item->value  = TXDID_MAX +  (*s - 'A');
585
586                     item->helpid = TXWH_USE_WIN_HELP; // from list-window itself
587
588                     item->index  = 1;          // drive-letter is quick-select
589                     if ((!flop) && (*s < 'C')) // simulate floppy info ?
590                     {
591                        sprintf( item->text, "%s             FAT",  drive);
592                        sprintf( item->desc, "Diskette drive %s   Status "
593                                             "not determined yet.", drive);
594                     }
595                     else
596                     {
597                        ULONG   rc    = NO_ERROR;
598                        ULONG   frees = 0;      // Free sectors
599                        ULONG   total = 0;      // Total sectors
600                        USHORT  bps;            // Sectorsize
601                        TXTM    fsys;
602                        TXTM    detail;
603                        TXTS    label;
604
605                        TxFsAutoFailCriticalErrors( TRUE); // avoid Not-ready pop-ups
606                        TxFsType( drive, fsys, detail);
607
608                        TxFsVolumeLabel( drive, label);
609                        if (strcmp( label, TXFS_NOTREADY) != 0) // no label access
610                        {
611                           if (strcmp( fsys, "UNKNOWN") != 0) // unknown filesystem
612                           {
613                              rc = TxFsSpace( drive, &frees, &total, &bps);
614                           }
615                        }
616                        else
617                        {
618                           rc = TX_INVALID_DRIVE;
619                        }
620                        TRACES(( "Drive %s  label: '%s' fsys: '%s' detail: '%s'\n",
621                                  drive, label, fsys, detail));
622                        if (rc == NO_ERROR)
623                        {
624                           sprintf( item->text, "%s %-11.11s %-8.8s %9.1lf MiB",
625                                    drive, label, fsys,
626                                   (total == 0) ? 0.0 : TXS2MB( total, bps));
627                           TRACES(("text: %d '%s'\n", strlen(item->text), item->text));
628                           TRACES(("t*:%8.8lx  d*:%8.8lx\n", item->text,  item->desc));
629                           TRACES(("total:%lu  frees:%lu  bps:%hu\n", total, frees, bps));
630
631                           sprintf( item->desc, "Drive %s %-11.11s %-8.8s Free: %9.1lf MiB  %s",
632                                    drive, label, fsys,
633                                    (frees == 0) ? 0.0 : TXS2MB( frees, bps), detail);
634                        }
635                        else
636                        {
637                           sprintf( item->text, "%s %-11.11s %-8.8s", drive, label, fsys);
638                           TRACES(("text: %d '%s'\n", strlen(item->text), item->text));
639                           sprintf( item->desc, "Drive %s   Removable not ready "
640                                                "or unknown filesystem", drive);
641                        }
642                        TxFsAutoFailCriticalErrors( FALSE); // enable criterror handler
643                     }
644                     TRACES(("desc: %d '%s'\n", strlen(item->desc), item->desc));
645                  }
646               }
647               if (*s == curdrive)
648               {
649                  list->selected = i;           // make this the selected one
650               }
651            }
652         }
653      }
654   #endif
655   if (list == NULL)                            // empty sofar ?
656   {
657      list = TxSelEmptyList( "- No volumes matching the criteria -",
658            "No volumes found that match the criteria for this list");
659   }
660   RETURN( list);
661}                                               // end 'TxFsDriveSelist'
662/*---------------------------------------------------------------------------*/
663#endif                                          // USEWINDOWING
664
665
666/*****************************************************************************/
667// Determine attached fstype, e.g. HPFS for specified drive
668/*****************************************************************************/
669BOOL TxFsType                                   // RET   FS type resolved
670(
671   char               *drive,                   // IN    Drive specification
672   char               *fstype,                  // OUT   Attached FS type
673   char               *details                  // OUT   details (UNC) or NULL
674)
675{
676   BOOL                rc = FALSE;
677   #if defined (WIN32)
678      TXTS             DriveRoot;
679      ULONG            ulMaxCompLen;
680      ULONG            ulFsFlags;
681   #elif defined (DOS32)
682      union  REGS      regs;
683      USHORT           drtype;
684   #elif defined (LINUX)
685      FILE            *mnt;
686      TXLN             line;
687      TXTM             mount;
688      TXTM             rest;
689      TXTM             device;
690   #else
691      FSQBUFFER2   *fsinfo;                     // Attached FS info
692      ULONG         fsdlen = 2048;              // Fs info data length
693   #endif
694
695   ENTER();
696   strcpy(fstype, "none");
697   if (details)
698   {
699      strcpy(details, "");
700   }
701
702   #if defined (WIN32)
703      sprintf(DriveRoot, "%c:\\", drive[0]);
704      rc = GetVolumeInformation( DriveRoot,
705                                 NULL, 0,       // no volume name
706                                 NULL,          // no volume serialnr
707                                 &ulMaxCompLen,
708