Mail Archives: djgpp-workers/2001/08/15/02:00:38
Test code. But I think it does what we need!
1) If SFN available from 7160 we use it.
2) If SFN name create fails, try LFN _chmod call to see if exists
(this will also show existence of devices on Win2K)
3) If exists try to open with name using SFN interrupt. This should
handle NUL, /dev/null (translated to NUL) or CON, etc.
4) If fail, just use LFN open call. This will then succeed for
./nul (or any-existing-directory/nul) for checking existence. If
anyone fstat() the handle or dev info it it will be bogus, but this
is our last shot. Note, if they call access instead we should be OK.
fstat() on the handles from this code look good, as do dev info calls.
What do you guys think? I can re-write this tomorrow for review if
it seems sound. For files we do one extra interrupt (sfn translation).
For devices 2-3 extra, but that's pretty rare.
*** _open.c_ Tue Aug 14 23:14:02 2001
--- _open.c Wed Aug 15 00:50:00 2001
***************
*** 2,5 ****
--- 2,6 ----
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+ #include <stdio.h>
#include <libc/stubs.h>
#include <string.h>
*************** _open(const char* filename, int oflag)
*** 29,32 ****
--- 30,77 ----
return rv;
+ if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532) {
+ /* Windows 2000 or XP; or NT with LFN TSR. Windows 2000 behaves
+ badly when using IOCTL and write-truncate calls on LFN handles.
+ We convert the long name to a short name and open existing files
+ via short name. New files use LFN, but we know they aren't
+ character devices. */
+ r.x.ax = 0x7160;
+ r.x.cx = 1; /* Get short name equivalent */
+ r.x.ds = __tb_segment;
+ r.x.si = __tb_offset;
+ r.x.es = __tb_segment;
+ r.x.di = __tb_offset + _put_path(filename);
+ __dpmi_int(0x21, &r);
+ if(!(r.x.flags & 1)) {
+ r.x.ax = 0x6c00;
+ r.x.bx = (oflag & 0xff);
+ r.x.dx = 1; /* Open existing file */
+ r.x.si = r.x.di;
+ goto do_open;
+ } else {
+ /* If it failed, either file doesn't exist or is device */
+ printf("Tried 7160 on \"%s\" and it failed (%d).\n",filename,r.x.ax);
+ /* r.x.ax = 0x7143;
+ r.h.bl = 0;
+ r.x.dx = __tb_offset;
+ _put_path(filename);
+ __dpmi_int(0x21, &r);
+ if(!(r.x.flags & 1)) { */
+ if(_chmod(filename,0) != -1) {
+ printf("Tried 7143 on \"%s\" OK.\n",filename);
+ _put_path(filename); /* since printf above nuked it */
+ r.x.ax = 0x6c00;
+ r.x.bx = (oflag & 0xff);
+ r.x.dx = 1; /* Open existing file */
+ r.x.cx = 0;
+ r.x.si = __tb_offset;
+ __dpmi_int(0x21, &r);
+ if(!(r.x.flags & 1)) { /* Fail on open. Must be directory? */
+ goto do_hset;
+ }
+ }
+ }
+ /* On failure we try the old way */
+ }
if(use_lfn) {
r.x.ax = 0x716c;
*************** _open(const char* filename, int oflag)
*** 55,61 ****
}
}
- r.x.cx = 0;
r.x.ds = __tb_segment;
_put_path(filename);
__dpmi_int(0x21, &r);
if(r.x.flags & 1)
--- 100,107 ----
}
}
r.x.ds = __tb_segment;
_put_path(filename);
+ do_open:
+ r.x.cx = 0;
__dpmi_int(0x21, &r);
if(r.x.flags & 1)
*************** _open(const char* filename, int oflag)
*** 64,67 ****
--- 110,114 ----
return -1;
}
+ do_hset:
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
- Raw text -