news:rs5sq7hme11emommn...@4ax.com...
> On Fri, 11 May 2012 17:56:43 -0400, "Rod Pemberton"
> <do_no...@notemailntt.cmm> wrote:
...
> Not to "dis" [Odi's LFN] tools as I can see a real need for them, [...]
Oh, I just thought someday, maybe someone, might be skilled enough to take
his source and make it into a TSR ...
> I am trying to provide lfn support to programs that can use or
> require long file names including the file manager
> that I am developing for one of my old applications as well as DJGPP.
Well, I've got few thoughts on that.
First, I forgot about it, but I wrote a test program to see which LFN
functions Windows 98, DOSLFN, and LFNDOS support. It's got RBIL interrupt
notes, probably copyrighted, that I need to remove ... It may save you some
time. It appears to be DJGPP only. I'll post a clean version after my .sig
to keep it separate from the other list below.
Second, I extended a program called rpmunpack.c for DJGPP and OpenWatcom for
LFN use. It uses 3 functions: 0x7156, 0x716C, and 0x3E. I'm not sure if
there is a difference between the two postings:
http://groups.google.com/group/openwatcom.contributors/msg/407305aa1df591de
http://groups.google.com/group/comp.os.msdos.djgpp/msg/07dac4062df95adc
Third, most of my other LFN-aware programs uses 0x71a0 and 0x7160
exclusively. AFAIK, I've not posted those functions. They're implemented
similarly to the two 0x71xx functions in rpmunpack.c. Very simple test
functions are also in my test program below. But, I do explain how I've
used 0x71a0 and 0x7160 at the end of this post:
http://groups.google.com/group/comp.os.msdos.djgpp/msg/6f05e7dd065ebbc1
Fourth, I compiled a bunch of info on DJGPP interrupt usage. I just merged
the LFN relevant info into the list below. It's for DJGPP v2.03. v2.04
supports symlinks, so there might be a few more C functions calling LFN
functions. So, if you use DJGPP, you'll have an idea of which C functions
call which LFN functions. I quickly compiled the info for personal use ...
years ago. So, I can't be certain I got everything. Sometimes an interrupt
number is split, e.g., instead of 0x710d, it's 0x71 and 0x0d, or worse ...
0x7160 is is interesting in that it has 3 sub-functions. The comment below
explains.
5704h ; LFN get last access date and time
5704 DJGPP _lfn_time
5705h ; LFN set last access date and time
5705 DJGPP utime
5706h ; LFN get creation date and time
5706 DJGPP _lfn_time
5707h ; LFN set creation date and time
5707 DJGPP (not found)
710Dh ; LFN reset drive
710d DJGPP _flush_disk_cache
7139h ; LFN create directory
7139 DJGPP mkdir
713Ah ; LFN remove directory
713a DJGPP remove
713a DJGPP rmdir
713Bh ; LFN set current directory
713b DJGPP __chdir
7141h ; LFN delete file
7141 DJGPP remove
7143h ; LFN get/set file attributes
7143 DJGPP _chmod
7143 DJGPP _open
7143 DJGPP utime
7147h ; LFN get current directory
7147 DJGPP __get_current_directory
7147 DJGPP __getcwd
714Eh ; LFN find first file
714e DJGPP findfirst
714Fh ; LFN find next file
714f DJGPP findnext
7156h ; LFN move (rename) file
7156 DJGPP _rename
7160h ; LFN truename FPN (CL=00h), SFN (CL=01h), LFN (CL=02h)
7160h ; LFN /* FPN FullPathName, SFN ShortFileName, LFN LongFileName */
7160 DJGPP _truename
7160 DJGPP _open direct_exec_tail_1
7160 DJGPP _get_current_directory
7160 DJGPP symlink
7160 DJGPP _getcwd
716Ch ; LFN create/open file
716c DJGPP _open
716c DJGPP _creat
716c DJGPP _creatnew
71A0h ; LFN get volume information
71a0 DJGPP _get_volume_info
71A1h ; LFN terminate FindFirst/FindNext
71a1 DJGPP findfirst
71a1 DJGPP findnext
71a1 DJGPP _lfn_find_close
71A6h ; LFN get file information
71a6 DJGPP get_sft_entry
71A7h ; LFN time conversion DOS_to_FILE (BL=00h), FILE_to_DOS (BL=01h)
71a7 DJGPP (not found)
71A8h ; LFN generate short filename
71a8 DJGPP _lfn_gen_short_fname
71A9h ; LFN server create/open file
71a9 DJGPP (not found)
71AAh ; LFN SUBST create (BH=00h), terminate (BH=01h), query (BH=02h)
71aa DJGPP (not found)
HTH,
Rod Pemberton
PS. Four comments and one print statement near the bottom have wrapped.
/* LFNTST.C by Rod Pemberton */
/* This program inspired by Andrew Crabtree's LFNTEST.ASM (NT-LFN driver) */
/* (I got tired of working in assembly... :{ */
/* To reduce coding issues, as much code as possible came from within
DJGPP... */
/* This program was originally used to try to improve Chris Jone's LFNDOS
driver */
/* However, Henrik Haftmann's DOSLFN driver works perfectly */
/* An #define below decides if you have a LFN test program or clean LFN
library */
/* gcc -o LFNTEST.EXE LFNTEST.C */
#include <dir.h> /* ffblk ffblklfn */
#include <dos.h> /* _get_drive */
#include <go32.h> /* __tb _dos_ds */
#include <dpmi.h> /* __dpmi_int */
#include <libc/dosio.h> /* __tb_segment __tb_offset _put_path
_put_path2 */
#include <stdio.h> /* printf */
#include <ctype.h>
#include <stdlib.h> /* malloc */
#include <strings.h> /* malloc */
#include <sys/movedata.h> /* movedata dosmemget */
#include <sys/farptr.h> /* farpeekb */
#include <fcntl.h> /* _get_volume_info */
__dpmi_regs r;
#define dot_char(x) (isprint(x)?(x):('.'))
void dump_tb(void)
{
int ctr;
for (ctr=0;ctr<1024;ctr++)
printf("%c",dot_char(_farpeekb(_dos_ds,__tb+ctr)));
}
void dump_tbh(void)
{
int ctr;
for (ctr=0;ctr<1024;ctr++)
printf("%02X",_farpeekb(_dos_ds,__tb+ctr));
}
void hex(unsigned long func)
{
printf ("0x%04lX ",func);
}
void hexnl(unsigned long func)
{
hex(func);
printf (" \n");
}
void pass(unsigned long func)
{
hex(func);
printf ("Passed! \n");
}
void fail(unsigned long func)
{
hex(func);
printf ("Failed! \n");
}
void pass_fail(unsigned long func)
{
if (!(r.x.flags & 1))
pass(func);
else
fail(func);
}
void dump_st(char *st)
{
int ctr,stl;
stl = strlen(st);
// hexnl(stl);
for (ctr=0;ctr<=stl;ctr++)
printf("%c",*st++);
printf("\n");
}
void dump_sth(char *st)
{
int ctr,stl;
stl = strlen(st);
// hexnl(stl);
for (ctr=0;ctr<=stl;ctr++)
printf("%02X",*st++);
printf("\n");
}
void lfn_710D(int drive)
{
r.x.ax = 0x710d;
r.x.cx = 1;
r.x.dx = drive;
r.x.flags |= 1;
__dpmi_int (0x21, &r);
}
void lfn_71A0(char *mpath)
{
dosmemput( mpath, 32,__tb);
r.x.ax = 0x71a0;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + 260;
r.x.cx = 32;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget(__tb+260, 32, mpath);
}
void lfn_7139(char *mpath)
{
dosmemput(mpath, 260,__tb);
r.x.ax = 0x7139;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_713B(char *mpath)
{
dosmemput( mpath, 260,__tb);
r.x.ax = 0x713b;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_7147(char *mpath, int drive)
{
r.x.ax = 0x7147;
r.h.dl = drive;
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget(__tb, 260, mpath);
}
void lfn_71A8(char *mpath, int dh)
{
dosmemput(mpath, 255, __tb);
r.x.ax = 0x71a8;
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + 260;
r.h.dh = dh;
r.h.dl = 0x11;
r.x.flags |= 1;
__dpmi_int (0x21, &r);
dosmemget(__tb+260, 255, mpath);
mpath[11+r.h.dh]=0;
}
void lfn_716C(char *mpath, unsigned *fhandle)
{
dosmemput( mpath, 260,__tb);
r.x.ax = 0x716c;
r.x.bx = 0x0002;
r.x.cx = 0;
r.x.dx = 0x0011; /* create, open if exists */
// r.x.dx = 0x0010; /* create, fail if exists */
// r.x.dx = 0x0012; /* create, truncate if exists */
// r.x.dx = 0x0001; /* open, fail if does not exist */
// r.x.dx = 0x0002; /* truncate, fail if does not exist */
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.di = 0;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
*fhandle =
r.x.ax;
}
void lfn_7160(char *mpath, int cl)
{
dosmemput( mpath, 261,__tb);
r.x.ax = 0x7160;
r.h.cl = cl;
r.h.ch = 0;
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + 261;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget(__tb+261, 255, mpath);
}
/*
void lfn_todostime(, unsigned *xtime)
{
dosdate = day + (mon<<5) + ((year-1980)<<9);
dostime = sec/2 + (min<<5) + (hour<<11);
*xtime = r.x.dx;
*xtime = (*xtime << 16) |
r.x.cx;
}
void lfn_dostimeto(, unsigned *xtime)
{
dosdate = day + (mon<<5) + ((year-1980)<<9);
dostime = sec/2 + (min<<5) + (hour<<11);
*xtime = r.x.dx;
*xtime = (*xtime << 16) |
r.x.cx;
}
*/
void lfn_5704(unsigned fhandle, unsigned *xtime)
{
r.x.ax = 0x5704;
r.x.bx = fhandle;
r.x.flags |= 1;
__dpmi_int (0x21, &r);
*xtime = r.x.dx;
*xtime = (*xtime << 16) |
r.x.cx;
}
void lfn_5705(unsigned fhandle, unsigned xtime)
{
r.x.ax = 0x5705;
r.x.bx = fhandle;
r.x.cx = xtime & 0xFFFF;
r.x.dx = xtime >> 16;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_5706(unsigned fhandle, unsigned *xtime)
{
r.x.ax = 0x5706;
r.x.bx = fhandle;
r.x.flags |= 1;
__dpmi_int (0x21, &r);
*xtime = r.x.dx;
*xtime = (*xtime << 16) |
r.x.cx;
}
void lfn_5707(unsigned fhandle, unsigned xtime)
{
r.x.ax = 0x5707;
r.x.bx = fhandle;
r.x.cx = xtime & 0xFFFF;
r.x.dx = xtime >> 16;
r.x.si = 0;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_71A6(unsigned fhandle)
{
r.x.ax = 0x71a6;
r.x.bx = fhandle;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
// dosmemget(__tb, 0x34, ?buf);
}
void lfn_7156(char *mpath, char *mpath2)
{
dosmemput( mpath, 260,__tb);
dosmemput( mpath2, 260,__tb+260);
r.x.ax = 0x7156;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + 260;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_7141(char *mpath, int si)
{
dosmemput( mpath, 260,__tb);
r.x.ax = 0x7141;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.si = si;
r.h.cl = 0x0;
r.h.ch = 0x0;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_713A(char *mpath)
{
dosmemput( mpath, 260,__tb);
r.x.ax = 0x713a;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_714E(char *mpath, char *mpath2, unsigned *fhandle)
{
dosmemput( mpath, 260,__tb);
r.x.ax = 0x714e;
r.h.cl = 0;
r.h.ch = 0;
r.x.si = 1;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + 260;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
*fhandle =
r.x.ax;
dosmemget(__tb+260+0x2C, 260, mpath);
dosmemget(__tb+260+0x130, 14, mpath2);
}
void lfn_714F(char *mpath, char *mpath2, unsigned fhandle)
{
r.x.ax = 0x714f;
r.x.bx = fhandle;
r.x.si = 1;
r.x.es = __tb_segment;
r.x.di = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget(__tb+0x2C, 260, mpath);
dosmemget(__tb+0x130, 14, mpath2);
}
void lfn_71A1(unsigned fhandle)
{
r.x.ax = 0x71a1;
r.x.bx = fhandle;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_3E(unsigned fhandle)
{
r.h.ah = 0x3E;
r.x.bx = fhandle;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_71AA(char *mpath, int drive, int bh)
{
dosmemput( mpath, 261,__tb);
r.x.ax = 0x71AA;
r.h.bh = bh;
r.h.bl = drive;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget( __tb, 261, mpath);
}
#if 0
void lfn_7143(char *mpath, int bl, unsigned cx, unsigned di)
{
dosmemput( mpath, 260,__tb);
r.x.ax = 0x7143;
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
r.h.bl = bl;
r.x.cx = cx;
r.x.di = di;
r.x.si = 0;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
void lfn_71A7(char *qwordh, char *qwordl, unsigned *xtime, int bl)
{
dosmemput( qwordh, 4,__tb);
dosmemput( qwordl, 4,__tb+4);
r.x.ax = 0x71A7;
r.h.bl = bl;
r.h.bh = 0;
r.x.cx = xtime & 0xFFFF;
r.x.dx = xtime >> 16;
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget(__tb, 4, qwordh);
dosmemget(__tb+4, 4, qwordl);
*xtime = r.x.dx;
*xtime = (*xtime << 16) |
r.x.cx;
}
/* ? */
void lfn_71A9()
{
dosmemput( mpath, 261,__tb);
r.x.ax = 0x71A9;
r.h.cl = cl;
r.h.ch = 0;
r.x.ds = __tb_segment;
r.x.si = __tb_offset;
r.x.es = __tb_segment;
r.x.di = __tb_offset + 261;
r.x.flags |= 1;
__dpmi_int(0x21, &r);
dosmemget(__tb+261, 255, mpath);
r.x.flags |= 1;
__dpmi_int(0x21, &r);
}
#endif
int main (void){
char *path,*path2;
unsigned fh,ftim,drive;
path = malloc(260);
path2 = malloc(260);
if (path==NULL||path2==NULL)
printf("error malloc\n");
/* LFN driver installation check, calls 0x71A0 */
_dos_getdrive(&drive);
sprintf(path,"%c:\\", 'A' - 1 + drive);
if ((_get_volume_info(path,0,0,0) & _FILESYS_LFN_SUPPORTED) ==0)
{
printf("No LFN support.");
exit(0);
}
printf("Testing Function 0x710D (Reset Drive) \n");
lfn_710D(0);
pass_fail(0x710d);
printf("\n");
printf("Testing LFN Function 0x71A0 (Get Volume Info) \n");
strcpy(path,"C:\\");
printf("%s\n",path);
lfn_71A0(path);
printf("%s\n",path);
pass_fail(0x71A0);
printf("\n");
printf("Testing LFN Function 0x7139 (Make Directory) \n");
strcpy(path,"C:\\TestMe LongName");
printf("%s\n",path);
lfn_7139(path);
pass_fail(0x7139);
printf("\n");
printf("Testing LFN Function 0x713B (Change Directory) \n");
strcpy(path,"C:\\TestMe LongName");
printf("%s\n",path);
lfn_713B(path);
pass_fail(0x713B);
printf("\n");
printf("Testing LFN Function 0x7147 (Get Current Directory) \n");
strcpy(path,"");
lfn_7147(path,0);
printf("%s\n",path);
pass_fail(0x7147);
printf("\n");
printf("Testing Function 0x71A8 (Generate Short Filename) \n");
strcpy(path,"Big Long Name to Test.tst");
printf("%s\n",path);
lfn_71A8(path,0);
printf("%s\n",path);
pass_fail(0x71A8);
strcpy(path,"Big Long Name to Test.tst");
lfn_71A8(path,1);
printf("%s\n",path);
pass_fail(0x71A8);
printf("\n");
// setup second file for 714F
strcpy(path,"Second Long Name to Test.tst");
lfn_716C(path,&fh);
lfn_3E(fh);
printf("Testing LFN Function 0x716C (Create/Open File) \n");
strcpy(path,"Big Long Name to Test.tst");
printf("%s\n",path);
lfn_716C(path,&fh);
pass_fail(0x716C);
printf("\n");
printf("Testing LFN Function 0x7160 (Get True/Short/Long Name) \n");
printf("Testing CL = 0x0 \n");
strcpy(path,"Big Long Name to Test.tst");
printf("%s\n",path);
lfn_7160(path,0);
printf("%s\n",path);
pass_fail(0x7160);
printf("\n");
printf("Testing CL = 0x1 \n");
strcpy(path,"Big Long Name to Test.tst");
printf("%s\n",path);
lfn_7160(path,1);
printf("%s\n",path);
pass_fail(0x7160);
printf("\n");
printf("Testing CL = 0x2 \n");
strcpy(path,"BIGLON~1.TST");
printf("%s\n",path);
lfn_7160(path,2);
printf("%s\n",path);
pass_fail(0x7160);
printf("\n");
printf("Testing Function 0x5704 (Get Last Access) \n");
lfn_5704(fh,&ftim);
pass_fail(0x5704);
printf("\n");
printf("Testing Function 0x5705 (Set Last Access) \n");
lfn_5705(fh,ftim);
pass_fail(0x5705);
printf("\n");
printf("Testing Function 0x5706 (Get Creation Date/Time) \n");
lfn_5706(fh,&ftim);
pass_fail(0x5706);
printf("\n");
printf("Testing Function 0x5707 (Set Creation Date/Time) \n");
lfn_5707(fh,ftim);
pass_fail(0x5707);
printf("\n");
printf("Testing LFN Function 0x71A6 (Get File Info By Handle) \n");
lfn_71A6(fh);
pass_fail(0x71A6);
printf("\n");
/* can't rename an open file in W98, must close first */
printf("Testing Function 0x3E (Close File) \n");
lfn_3E(fh);
pass_fail(0x3E);
printf("\n");
printf("Testing LFN Function 0x714E (Find First File) \n");
strcpy(path,"*.*");
strcpy(path2,"");
printf("%s\n",path);
lfn_714E(path,path2,&fh);
printf("%s\n",path);
printf("%s\n",path2);
pass_fail(0x714E);
printf("\n");
printf("Testing LFN Function 0x714F (Find Next File) \n");
strcpy(path,"");
strcpy(path2,"");
lfn_714F(path,path2,fh);
printf("%s\n",path);
printf("%s\n",path2);
pass_fail(0x714F);
printf("\n");
printf("Testing LFN Function 0x71A1 (Terminate Directory Search) \n");
lfn_71A1(fh);
pass_fail(0x71A1);
printf("\n");
printf("Testing Function 0x7156 (Rename File) \n");
strcpy(path,"Big Long Name to Test.tst");
printf("%s\n",path);
strcpy(path2,"Another Big Long name.tst");
printf("%s\n",path2);
lfn_7156(path,path2);
pass_fail(0x7156);
printf("\n");
printf("Testing Function 0x7156 (Rename File) \n");
strcpy(path,"Another Big Long name.tst");
printf("%s\n",path);
strcpy(path2,"junkit.tst");
printf("%s\n",path2);
lfn_7156(path,path2);
pass_fail(0x7156);
printf("\n");
//delete second file for 714F
strcpy(path,"Second Long Name to Test.tst");
lfn_7141(path,0);
printf("Testing Function 0x7141 (Delete File) \n");
strcpy(path,"junkit.tst");
printf("%s\n",path);
lfn_7141(path,0);
pass_fail(0x7141);
printf("\n");
strcpy(path,"*.*");
lfn_7141(path,1);
printf("Testing Function 0x71AA (Create/Terminate/Query Subst) \n");
printf("Testing BH = 0x0 \n");
strcpy(path,"C:\\TestMe LongName");
printf("%s\n",path);
lfn_71AA(path,1,0);
pass_fail(0x71AA);
printf("\n");
printf("Testing BH = 0x2 \n");
strcpy(path,"");
lfn_71AA(path,1,2);
printf("%s\n",path);
pass_fail(0x71AA);
printf("\n");
printf("Testing BH = 0x1 \n");
strcpy(path,"");
lfn_71AA(path,1,1);
pass_fail(0x71AA);
printf("\n");
printf("Testing LFN Function 0x713A (Remove Directory) \n");
strcpy(path,"..");
lfn_713B(path);
strcpy(path,"C:\\TestMe LongName");
printf("%s\n",path);
lfn_713A(path);
pass_fail(0x713A);
printf("\n");
#if 0
printf("Testing Function 0x7143 (Extended Get/Set File Attributes)
\n");
printf("Testing BL = 0x0 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x1 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x2 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x3 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x4 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x5 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x6 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x7 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("Testing BL = 0x8 \n");
lfn_7143(path,? bl,cx,di);
pass_fail(0x7143);
printf("\n");
#endif
#if 0
printf("Testing Function 0x71A7 (Dos/File Time to File/Dos Time) \n");
printf("Testing BL = 0x0 \n");
lfn_71A7(qwh,qwl,&ftim,0);
pass_fail(0x71A7);
printf("\n");
printf("Testing BL = 0x1 \n");
lfn_71A7(&qwh,&qwl,ftim,1);
pass_fail(0x71A7);
printf("\n");
#endif
#if 0
printf("Testing Function 0x71A9 (Server Create/Open File) \n");
lfn_71A9();
#endif
exit(0);
}