From: sandmann AT clio DOT rice DOT edu (Charles Sandmann) Message-Id: <10108160635.AA13428@clio.rice.edu> Subject: Better _open.c, test program To: eliz AT is DOT elta DOT co DOT il Date: Thu, 16 Aug 2001 01:35:10 -0500 (CDT) Cc: djgpp-workers AT delorie DOT com (DJGPP developers), acottrel AT ihug DOT com DOT au In-Reply-To: X-Mailer: ELM [version 2.5 PL2] Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com _open.c cleaned up a bit. Testing looks good. Test program below, use it to look at results from _open linked in (plus see what happens on other calls using old _open). Please make comments, then we test? *** _open.c_ Tue Aug 14 23:14:02 2001 --- _open2.c Thu Aug 16 01:16:08 2001 *************** _open(const char* filename, int oflag) *** 30,31 **** --- 30,73 ---- + 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; /* Long name to convert - putpath */ + r.x.es = __tb_segment; + r.x.di = __tb_offset + _put_path(filename); /* Short name destination */ + __dpmi_int(0x21, &r); + if(!(r.x.flags & 1)) { /* Get short name success */ + 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 { + /* Short name get failed, file doesn't exist or is device (same error) */ + r.x.ax = 0x7143; /* Get attributes */ + r.h.bl = 0; + r.x.dx = __tb_offset; /* Treat original name as short */ + __dpmi_int(0x21, &r); /* This is same as lfn _chmod */ + if(!(r.x.flags & 1)) { /* Name exists */ + r.x.ax = 0x6c00; + r.x.bx = (oflag & 0xff); + r.x.dx = 1; /* Open existing file */ + r.x.si = __tb_offset; + r.x.cx = 0; + __dpmi_int(0x21, &r); + if(!(r.x.flags & 1)) { /* Success! */ + goto do_hset; + } + /* Fail on short name open after _chmod said OK. + Device with directory? We should re-try with LFN. + Permission? Readonly file? We should quit. + Let it fall through to the LFN open which should succeed. */ + } + } + } if(use_lfn) { *************** _open(const char* filename, int oflag) *** 56,60 **** } - r.x.cx = 0; r.x.ds = __tb_segment; _put_path(filename); __dpmi_int(0x21, &r); --- 98,103 ---- } r.x.ds = __tb_segment; _put_path(filename); + do_open: + r.x.cx = 0; __dpmi_int(0x21, &r); *************** _open(const char* filename, int oflag) *** 65,66 **** --- 108,110 ---- } + do_hset: __file_handle_set(r.x.ax, O_BINARY); \\test\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #include #include #include #include #include #include #include #include #include #define TEST argv[1] int main(int argc, char** argv) { int i; struct stat tstat; for(i=0;i<5;i++) printf("Dev info[%d]: 0x%x\n",i,_get_dev_info(i)); if(_USE_LFN) printf("Long names are active.\n"); else printf("Long names are *NOT* active.\n"); if(argc != 2) return printf("Usage: test \n"); printf("_chmod: 0x%x\n",_chmod(TEST,0)); if(_USE_LFN) { __dpmi_regs r; 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(TEST); __dpmi_int(0x21, &r); if(!(r.x.flags & 1)) { char longname[255]; dosmemget(__tb_segment*16+r.x.di,255,longname); printf("7160 returned %s\n",longname); } else { printf("7160 failure 0x%x\n",r.x.ax); } } { char name[255]; if(_truename(TEST,name)) printf("Truename returned %s\n",name); else printf("Truename failed.\n"); } i = open(TEST, O_WRONLY | O_BINARY | O_APPEND, S_IREAD | S_IWRITE); printf("Append Handle=%d\n",i); printf("Dev info: 0x%x\n",_get_dev_info(i)); if(i != -1) { __dpmi_regs r; int fsbuff[16],j; r.x.ax = 0x71a6; r.x.bx = i; r.x.ds = __tb_segment; r.x.dx = 0; __dpmi_int(0x21, &r); if(r.x.flags & 1) printf("71a6 failure 0x%x\n",r.x.ax); else { dosmemget(__tb_segment*16,sizeof(fsbuff),fsbuff); printf("71a6:"); for(j=0;j<13;j++) printf(" 0x%x",fsbuff[j]); printf("\n"); } i = fstat(i, &tstat); printf("ret=%d atime=%d ctime=%d dev=%d ino=%d mode=%d mtime=%d nlink=%d size=%d blksiz=%d\n", i,tstat.st_atime,tstat.st_ctime,tstat.st_dev,tstat.st_ino,tstat.st_mode,tstat.st_mtime, tstat.st_nlink,tstat.st_size,tstat.st_blksize); /* _djstat_describe_lossage(stdout); */ } i = open(TEST, O_WRONLY | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE); printf("Trunc Handle=%d\n",i); printf("Dev info: 0x%x\n",_get_dev_info(i)); return 0; }