Skip to content

DOS Long File Name CRTL Extension

Jiri Malak edited this page Sep 15, 2021 · 16 revisions

DOS Long Filenames CRTL Extension

Although for the most part, the support of LFNs should be transparent when compiling, some changes in headers are necessary.

WCC/WCC386 should allow a new option, perhaps -lfn (to be decided), that predefines a __WATCOM_LFN__ macro to cause header files to allow larger values needed for long filenames. When a program is linked, there should be a WCL/WCL386/WLINK option to specify that LFN modules will be linked in to override the non-LFN clib functions. Perhaps a dos_lfn system will do the trick.

In addition to modifying older functions, some new functions could make themselves useful, such as a function to convert long filenames to short filenames. This way, the long filenames could be used in functions that only accept short filenames, without much difficulty for the programmer. It should be easy to add LFN support to any program so long as it can be compiled with OpenWatcom, as is the situation with DJGPP. Another useful feature would be to have a global int, such as _lfn_supported to be set t o 1 if there is an LFN TSR installed or 0 if there are no LFN TSRs installed.

For now, compatibility with Windows XP, NT (with NTLFN), and 2k is not an issue, but testing should be done exclusively in DOS environments; this includes pure DOS, DOSEMU, DOSBOX (does DOSLFN work in DOSBOX?, apparently not at this time), and possibly Windows 95 / 98, as long as an LFN driver functions correctly on the testing system. The functions should work both with and without an LFN driver installed in memory. After the above systems are found to be stable, work may begin to support other environmen ts, like Windows XP and 2k.

At this point in time the todo list is as followed:

  • Submit a patch - Done
  • Test really well for bugs with a complete clib - In Progress
  • Submit bugfixes if necessary - Done
  • Make it more complete if I missed some functions - In Progress (hopefully done)
  • Add LFN2SFN function and other helper functions - Done
  • Complete documentation - In progress
  • Testing in complex programs (such as wcc itself)

Functions that still need LFN support include:

  • unknown

The following values should be changed:

NAME_MAX   = 12  should be NAME_MAX   = 260
_MAX_PATH  = 144 should be _MAX_PATH  = 260
_MAX_DIR   = 130 should be _MAX_DIR   = 260
_MAX_FNAME = 9   should be _MAX_FNAME = 260
_MAX_EXT   = 5   should be _MAX_EXT   = 260
_MAX_NAME  = 13  should be _MAX_NAME  = 260

and the following structs would need modification:

struct find_t {
    char reserved[21];
    char attrib;
    unsigned short wr_time;
    unsigned short wr_date;
    unsigned long  size;
    char name[13];
};

should be

struct find_t {
    unsigned short cr_time; /* time of file creation      */
    unsigned short cr_date; /* date of file creation      */
    unsigned short ac_time; /* time of last file access   */
    unsigned short ac_date; /* date of last file access   */
    unsigned short lfnax;   /* DOS LFN search handle      */
    unsigned char  lfnsup;  /* DOS LFN support status     */
    char reserved[10];      /* reserved for use by DOS    */
    char attrib;            /* attribute byte for file    */
    unsigned short wr_time; /* time of last write to file */
    unsigned short wr_date; /* date of last write to file */
    unsigned long  size;    /* length of file in bytes    */
    char name[256];         /* null-terminated filename   */
};

and...

struct dirent {
    char               d_dta[21];
    char               d_attr;
    unsigned short int d_time;
    unsigned short int d_date;
    long               d_size;
    char               d_name[NAME_MAX+1];
    unsigned short     d_ino;
    char               d_first;
    char *             d_openpath;
};

should be

struct dirent {
    char               d_dta[10];       /* disk transfer area */
    unsigned short int d_ctime;         /* file's creation time */
    unsigned short int d_cdate;         /* file's creation date */
    unsigned short int d_atime;         /* file's last access time */
    unsigned short int d_adate;         /* file's last access date */
    unsigned short     d_lfnax;         /* DOS LFN search handle */
    unsigned char      d_lfnsup;        /* DOS LFN support status */
    char               d_attr;          /* file's attribute */
    unsigned short int d_time;          /* file's time */
    unsigned short int d_date;          /* file's date */
    long               d_size;          /* file's size */
    char               d_name[NAME_MAX+1];/* file's name */
    unsigned short     d_ino;           /* serial number (not used) */
    char               d_first;         /* flag for 1st time */
    char *             d_openpath;      /* path specified to opendir */
};

where the 21-byte reserved block would be replaced with actual values that could be filled with relevant LFN data, namely whether LFN is supported, the LFN find handle, the creation time, the creation date, the last access time, and the last access date. Structure members overlaying the previously defined 21-byte DTA would naturally only be available when not using SFN system/drive.

The name[] value would be extended to support a full long filename and the same struct would be at the same time compatible with the non-LFN equivalent - to the extent that on DOS without LFN and non-DOS systems the layout of existing fields and size of the structure would be completely unchanged, while on new LFN-enabled DOS builds the structure would have different size and layout but still be source compatible and only require a recompilation to use.

Working status for functions

Function Header Implementation Status
mkdir direct.h working
chdir direct.h working
rmdir direct.h working
getcwd/_getdcwd direct.h working
opendir direct.h working
readdir direct.h working
closedir direct.h working
_dos_creat dos.h working
_dos_creatnew
dos.h
working
_dos_open
dos.h
working
_dos_findfirst
dos.h
working
_dos_findnext
dos.h
working
_dos_getfileattr
dos.h
working
_dos_setfileattr
dos.h
working
_dos_findclose

dos.h

working

access

io.h

working (but not in Win2k, patches welcome)

chmod

io.h

working

open

io.h

working

unlink/remove

io.h

working

_findfirst

io.h

working but needs further testing

_findclose

io.h

needs further testing

_findnext

io.h

not working

execve

process.h

working (patch still to be committed)

spawnve

process.h

working (patch still to be committed)

stat/lstat

sys/stat.h

working

fopen

stdio.h

working

rename

stdio.h

working

Clone this wiki locally