home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / dos / dir / findfirs.c next >
Encoding:
C/C++ Source or Header  |  1996-08-31  |  2.7 KB  |  101 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <go32.h>
  9. #include <dpmi.h>
  10. #include <dir.h>
  11. #include <libc/dosio.h>
  12.  
  13. int
  14. findfirst(const char *pathname, struct ffblk *ffblk, int attrib)
  15. {
  16.   __dpmi_regs r;
  17.   int pathlen;
  18.   int use_lfn = _USE_LFN;
  19.  
  20.   if (pathname == 0 || ffblk == 0)
  21.   {
  22.     errno = EACCES;
  23.     return -1;
  24.   }
  25.  
  26.   pathlen = strlen(pathname) + 1;
  27.  
  28.   _put_path(pathname);
  29.   if(use_lfn) {
  30.  
  31.     /* si = 1 indicates DOS style dates, 0 means Win32 type dates.
  32.        DOS style dates are broken in some Win95 betas, build for either.
  33.        Release works with DOS date, it's faster, so use it. */
  34.     #define USEDOSDATE 1
  35.     #if USEDOSDATE == 1
  36.       #define _Win32_to_DOS (long)
  37.     #else
  38.       extern long _Win32_to_DOS(long long WinTime);
  39.     #endif
  40.  
  41.     r.x.ax = 0x714e;
  42.     r.x.cx = attrib;
  43.     r.x.dx = __tb_offset;
  44.     r.x.ds = __tb_segment;
  45.     r.x.di = __tb_offset + pathlen;
  46.     r.x.es = r.x.ds;
  47.     r.x.si = USEDOSDATE;
  48.     __dpmi_int(0x21, &r);
  49.     if(!(r.x.flags & 1)) {
  50.       struct ffblklfn ffblk32;
  51.       /* Recover results */
  52.       dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
  53.  
  54.       ffblk->ff_attrib = (char)ffblk32.fd_attrib;
  55.       *(long *)(&ffblk->ff_ftime) = _Win32_to_DOS(ffblk32.fd_mtime);
  56.       ffblk->ff_fsize = ffblk32.fd_size;
  57.       strcpy(ffblk->ff_name, ffblk32.fd_longname);
  58.       strcpy(ffblk->lfn_magic, "LFN32");
  59.  
  60.       /* If no wildcards, close the handle */
  61.       if(!strchr(pathname,'*') && !strchr(pathname,'?')) {
  62.         r.x.bx = r.x.ax;
  63.         r.x.ax = 0x71a1;
  64.         __dpmi_int(0x21, &r);
  65.         r.x.ax = 0;
  66.       }
  67.         
  68.       ffblk->lfn_handle = r.x.ax;
  69.       *(long *)(&ffblk->lfn_ctime) = _Win32_to_DOS(ffblk32.fd_ctime);
  70.       *(long *)(&ffblk->lfn_atime) = _Win32_to_DOS(ffblk32.fd_atime);
  71.  
  72.       return 0;
  73.     }
  74.   } else {
  75.  
  76.     #define _sizeof_dos_ffblk 44
  77.     /* There will be a _sizeof_dos_ffblk character return value from findfirst 
  78.        in the DTA.  Put the file name before this.  First set the DTA to be 
  79.        transfer buffer. */
  80.  
  81.     r.x.dx = __tb_offset + pathlen;
  82.     r.x.ds = __tb_segment;
  83.     r.h.ah = 0x1a;
  84.     __dpmi_int(0x21, &r);
  85.  
  86.     r.h.ah = 0x4e;
  87.     r.x.dx = __tb_offset;
  88.     r.x.ds = __tb_segment;
  89.     r.x.cx = attrib;
  90.     __dpmi_int(0x21, &r);
  91.     if(!(r.x.flags & 1)) {
  92.       /* Recover results */
  93.       dosmemget(__tb+pathlen, _sizeof_dos_ffblk, ffblk);
  94.       return 0;
  95.     }
  96.   }
  97.  
  98.   errno = __doserr_to_errno(r.x.ax);
  99.   return errno;
  100. }
  101.