delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/08/16/03:38:51

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
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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dpmi.h>
#include <go32.h>
#include <libc/dosio.h>

#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 <devnam>\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;
 }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019