Skip to content

DOS Long File Name CRTL Extension

Jiří Malák edited this page Nov 6, 2021 · 16 revisions

DOS Long File Name 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 macros definition are conditionally changed for LFN.

Macro DOS LFN DOS Windows OS/2
NAME_MAX 259 12 259 255
_MAX_PATH 256 144 256 256
_MAX_DIR 256 130 256 256
_MAX_FNAME 256 9 256 256
_MAX_EXT 256 5 256 256

The find_t structure

struct find_t {
    char            reserved[21];       /* 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[NAME_MAX+1];   /* null-terminated filename   */
};

and dirent structure

struct dirent {
    char                d_dta[21];          /* disk transfer area */
    char                d_attr;             /* file's attribute */
    unsigned short      d_time;             /* file's time */
    unsigned short      d_date;             /* file's date */
    long                d_size;             /* file's size */
    unsigned short      d_ino;              /* serial number (not used) */
    char                d_first;            /* flag for 1st time */
    char                *d_openpath;        /* path specified to opendir */
    char                d_name[NAME_MAX+1]; /* file's name */
};

must contain LFN-specific data. SFN-related DOS calls use a dedicated data area (21 bytes), but LFN-related calls do not. Therefore, this data area can be used for LFN-specific data and there is no need to change the find_t or dirent structure.

The following __doslfn_dta structure is used to store the required LFN data.

typedef struct __doslfn_dta {
    unsigned short  cr_time;  /* creation time */
    unsigned short  cr_date;  /* creation date */
    unsigned short  ac_time;  /* last access time */
    unsigned short  ac_date;  /* last access date */
    unsigned long   sign;     /* LFN signature */
    unsigned short  handle;   /* LFN search handle */
} __doslfn_dta;

It overlaps the reserved data area (21 bytes) in both structures. This structure is used only internally by the C run-time library, so it is not part of the public definition. The time/date fields are handled by appropriate C run-time library function. The sign and handle fields are used by LFN internal processing.

The length of the name field in the find_t and dirent structures is extended to support the entire long file name by changing the NAME_MAX macro. The LFN version of structure is a different size, but the layout is still the same and only recompilation is required.

Working status for functions

Function Header Implementation Status
mkdir, _mkdir, _wmkdir direct.h working
chdir, _chdir, _wchdir direct.h working
rmdir, _rmdir, _wrmdir direct.h working
getcwd, _getcwd, _wgetcwd direct.h working
opendir, _wopendir direct.h working
readdir, _wreaddir direct.h working
closedir, _wclosedir direct.h working
rewinddir, _wrewinddir direct.h working
_dos_creat dos.h working
_dos_creatnew dos.h working
_dos_open dos.h working
_dos_findfirst, _wdos_findfirst dos.h working
_dos_findnext, _wdos_findnext dos.h working
_dos_findclose, _wdos_findclose dos.h working
_dos_getfileattr dos.h working
_dos_setfileattr dos.h working
access, _access, _waccess io.h working (but not in Win2k, patches welcome)
chmod. _chmod, _wchmod io.h working
open, _open, _wopen io.h working
sopen, _sopen, _wsopen io.h working
unlink, _unlink, _wunlink io.h working
_findfirst, _wfindfirst io.h working but needs further testing
_findclose, _wfindclose io.h needs further testing
_findnext, _wfindnext io.h not working
execve, _execve process.h working (patch still to be committed)
spawnve, _spawnve process.h working (patch still to be committed)
stat, _stat, _wstat sys/stat.h working
fstat, _fstat sys/stat.h working
lstat sys/stat.h working
remove, _wremove stdio.h working
rename, _wrename stdio.h working
_tempnam, _wtempnam stdio.h working
_fullpath, _wfullpath stdlib.h working
_splitpath, _wsplitpath stdlib.h working
_splitpath2, _wsplitpath2 stdlib.h working
_searchenv, _wsearchenv stdlib.h working
utime, _utime, _wutime utime.h working
Clone this wiki locally