3 * NOV 1993 Erik Bos <erik@xs4all.nl>
5 * FindFile by Bob, hacked for dos & unixpaths by Erik.
7 * Bugfix by dash@ifi.uio.no: ToUnix() was called to often
21 #if defined(__linux__) || defined(sun)
24 #if defined(__NetBSD__) || defined(__FreeBSD__)
25 #include <sys/param.h>
26 #include <sys/mount.h>
29 #include <sys/statfs.h>
41 #ifndef WINE_INI_GLOBAL
42 /* Get the WINE_INI_GLOBAL definition from autoconf.h */
46 #define WINE_INI_USER "~/.winerc"
47 #define MAX_DOS_DRIVES 26
49 extern char WindowsDirectory
[256], SystemDirectory
[256],TempDirectory
[256];
51 char WindowsPath
[256];
53 static int max_open_dirs
= 0;
54 static int CurrentDrive
= 2;
56 struct DosDriveStruct
{ /* eg: */
57 char *rootdir
; /* /usr/windows */
58 char cwd
[256]; /* / */
59 char label
[13]; /* DRIVE-A */
60 unsigned int serialnumber
; /* ABCD5678 */
64 static struct DosDriveStruct DosDrives
[MAX_DOS_DRIVES
];
65 static struct dosdirent
*DosDirs
=NULL
;
68 BYTE ErrorClass
, Action
, ErrorLocus
;
70 int DOS_Error(int e
, int class, int el
)
73 Action
= SA_Ask4Retry
;
80 void errno_to_doserr(void)
84 DOS_Error (ShareViolation
, EC_Temporary
, EL_Unknown
);
87 DOS_Error (InvalidHandle
, EC_AppError
, EL_Unknown
);
90 DOS_Error (DiskFull
, EC_MediaError
, EL_Disk
);
95 DOS_Error (WriteProtected
, EC_AccessDenied
, EL_Unknown
);
98 DOS_Error (LockViolation
, EC_AccessDenied
, EL_Unknown
);
101 DOS_Error (FileNotFound
, EC_NotFound
, EL_Unknown
);
104 DOS_Error (CanNotMakeDir
, EC_AccessDenied
, EL_Unknown
);
108 DOS_Error (NoMoreFiles
, EC_MediaError
, EL_Unknown
);
111 DOS_Error (FileExists
, EC_Exists
, EL_Disk
);
114 dprintf_int(stddeb
, "int21: unknown errno %d!\n", errno
);
115 DOS_Error (GeneralFailure
, EC_SystemFailure
, EL_Unknown
);
121 static void ExpandTildeString(char *s
)
123 struct passwd
*entry
;
124 char temp
[1024], *ptr
= temp
;
138 if ( (entry
= getpwuid(getuid())) == NULL
)
143 strcpy(s
, entry
->pw_dir
);
144 s
+= strlen(entry
->pw_dir
);
149 /* Simplify the path in "name" by removing "//"'s, "/./"'s, and
150 ".."'s in names like "/usr/bin/../lib/test" */
151 static void DOS_SimplifyPath(char *name
)
156 dprintf_dosfs(stddeb
,"SimplifyPath: Before %s\n",name
);
159 while ((l
= strstr(name
,"//"))) {
160 strcpy(l
,l
+1); changed
= TRUE
;
162 while ((l
= strstr(name
,"/../"))) {
164 p
= strrchr(name
,'/');
165 if (p
== NULL
) p
= name
;
169 while ((l
= strstr(name
, "/./"))) {
170 strcpy(l
, l
+2); changed
= TRUE
;
173 dprintf_dosfs(stddeb
,"SimplifyPath: After %s\n",name
);
177 /* ChopOffSlash takes care to strip directory slashes from the
178 * end off the path name, but leaves a single slash. Multiple
179 * slashes at the end of a path are all removed.
182 void ChopOffSlash(char *path
)
184 char *p
= path
+ strlen(path
) - 1;
185 while ((*p
== '\\') && (p
> path
)) *p
-- = '\0';
191 if (*s
== '\\') *s
= '/';
192 *s
=tolower(*s
); /* umsdos fs can't read files without :( */
200 if (*s
== '/') *s
= '\\';
205 void DOS_InitFS(void)
208 char drive
[2], temp
[256];
210 GetPrivateProfileString("wine", "windows", "c:\\windows",
211 WindowsDirectory
, sizeof(WindowsDirectory
), WINE_INI
);
213 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
214 SystemDirectory
, sizeof(SystemDirectory
), WINE_INI
);
216 GetPrivateProfileString("wine", "temp", "c:\\windows",
217 TempDirectory
, sizeof(TempDirectory
), WINE_INI
);
219 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
220 WindowsPath
, sizeof(WindowsPath
), WINE_INI
);
222 ChopOffSlash(WindowsDirectory
);
223 ToDos(WindowsDirectory
);
225 ChopOffSlash(SystemDirectory
);
226 ToDos(SystemDirectory
);
228 ChopOffSlash(TempDirectory
);
229 ToDos(TempDirectory
);
232 ExpandTildeString(WindowsPath
);
234 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
235 DosDrives
[x
].serialnumber
= (0xEB0500L
| x
);
239 GetPrivateProfileString("drives", drive
, "*", temp
, sizeof(temp
), WINE_INI
);
240 if (!strcmp(temp
, "*") || *temp
== '\0') {
241 DosDrives
[x
].rootdir
= NULL
;
242 DosDrives
[x
].cwd
[0] = '\0';
243 DosDrives
[x
].label
[0] = '\0';
244 DosDrives
[x
].disabled
= 1;
247 ExpandTildeString(temp
);
249 DosDrives
[x
].rootdir
= strdup(temp
);
250 strcpy(DosDrives
[x
].rootdir
, temp
);
251 strcpy(DosDrives
[x
].cwd
, "/windows/");
252 strcpy(DosDrives
[x
].label
, "DRIVE-");
253 strcat(DosDrives
[x
].label
, drive
);
254 DosDrives
[x
].disabled
= 0;
256 DosDrives
[25].rootdir
= "/";
257 strcpy(DosDrives
[25].label
, "UNIX-FS");
258 DosDrives
[25].serialnumber
= 0x12345678;
259 DosDrives
[25].disabled
= 0;
261 /* Get the startup directory and try to map it to a DOS drive
262 * and directory. (i.e., if we start in /dos/windows/word and
263 * drive C is defined as /dos, the starting wd for C will be
264 * /windows/word) Also set the default drive to whatever drive
265 * corresponds to the directory we started in.
268 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++)
269 if (DosDrives
[x
].rootdir
!= NULL
)
270 strcpy( DosDrives
[x
].cwd
, "/" );
273 strcat(temp
, "/"); /* For DOS_GetDosFileName */
274 strcpy(DosDrives
[25].cwd
, temp
);
275 strcpy(temp
, DOS_GetDosFileName(temp
));
279 strcpy(DosDrives
[temp
[0] - 'A'].cwd
, &temp
[2]);
280 DOS_SetDefaultDrive(temp
[0] - 'A');
284 DOS_SetDefaultDrive(2);
287 for (x
=0; x
!=MAX_DOS_DRIVES
; x
++) {
288 if (DosDrives
[x
].rootdir
!= NULL
) {
289 dprintf_dosfs(stddeb
, "DOSFS: %c: => %-40s %s %s %X %d\n",
291 DosDrives
[x
].rootdir
,
294 DosDrives
[x
].serialnumber
,
295 DosDrives
[x
].disabled
);
299 for (x
=0; x
!=max_open_dirs
; x
++)
300 DosDirs
[x
].inuse
= 0;
302 dprintf_dosfs(stddeb
,"wine.ini = %s\n",WINE_INI
);
303 dprintf_dosfs(stddeb
,"win.ini = %s\n",WIN_INI
);
304 dprintf_dosfs(stddeb
,"windir = %s\n",WindowsDirectory
);
305 dprintf_dosfs(stddeb
,"sysdir = %s\n",SystemDirectory
);
306 dprintf_dosfs(stddeb
,"tempdir = %s\n",TempDirectory
);
307 dprintf_dosfs(stddeb
,"path = %s\n",WindowsPath
);
310 WORD
DOS_GetEquipment(void)
314 int parallelports
= 0;
318 /* borrowed from Ralph Brown's interrupt lists
320 bits 15-14: number of parallel devices
321 bit 13: [Conv] Internal modem
323 bits 11- 9: number of serial devices
325 bits 7- 6: number of diskette drives minus one
326 bits 5- 4: Initial video mode:
332 bit 2: [PS] =1 if pointing device
334 bit 1: =1 if math co-processor
335 bit 0: =1 if diskette available for boot
337 /* Currently the only of these bits correctly set are:
338 bits 15-14 } Added by William Owen Smith,
339 bits 11-9 } wos@dcs.warwick.ac.uk
344 if (DosDrives
[0].rootdir
!= NULL
)
346 if (DosDrives
[1].rootdir
!= NULL
)
351 for (x
=0; x
!=MAX_PORTS
; x
++) {
352 if (COM
[x
].devicename
)
354 if (LPT
[x
].devicename
)
357 if (serialports
> 7) /* 3 bits -- maximum value = 7 */
359 if (parallelports
> 3) /* 2 bits -- maximum value = 3 */
362 equipment
= (diskdrives
<< 6) | (serialports
<< 9) |
363 (parallelports
<< 14) | 0x02;
365 dprintf_dosfs(stddeb
, "DOS_GetEquipment : diskdrives = %d serialports = %d "
366 "parallelports = %d\n"
367 "DOS_GetEquipment : equipment = %d\n",
368 diskdrives
, serialports
, parallelports
, equipment
);
373 int DOS_ValidDrive(int drive
)
375 dprintf_dosfs(stddeb
,"ValidDrive %c (%d)\n",'A'+drive
,drive
);
377 if (drive
< 0 || drive
>= MAX_DOS_DRIVES
) return 0;
378 if (DosDrives
[drive
].rootdir
== NULL
) return 0;
379 if (DosDrives
[drive
].disabled
) return 0;
381 dprintf_dosfs(stddeb
, " -- valid\n");
385 static void DOS_GetCurrDir_Unix(char *buffer
, int drive
)
387 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
389 if (pTask
!= NULL
&& (pTask
->curdrive
& ~0x80) == drive
) {
390 strcpy(buffer
, pTask
->curdir
);
393 strcpy(buffer
, DosDrives
[drive
].cwd
);
397 char *DOS_GetCurrentDir(int drive
)
399 static char temp
[256];
401 if (!DOS_ValidDrive(drive
)) return 0;
403 DOS_GetCurrDir_Unix(temp
, drive
);
404 DOS_SimplifyPath( temp
);
408 dprintf_dosfs(stddeb
,"DOS_GetCWD: %c:%s\n", 'A'+drive
, temp
);
412 char *DOS_GetUnixFileName(const char *dosfilename
)
414 /* a:\windows\system.ini => /dos/windows/system.ini */
416 /* FIXME: should handle devices here (like LPT: or NUL:) */
418 static char dostemp
[256], temp
[256];
419 int drive
= DOS_GetDefaultDrive();
421 if (dosfilename
[0] && dosfilename
[1] == ':')
423 drive
= toupper(*dosfilename
) - 'A';
426 if (!DOS_ValidDrive(drive
)) return NULL
;
428 strncpy( dostemp
, dosfilename
, 255 );
431 strcpy(temp
, DosDrives
[drive
].rootdir
);
432 if (dostemp
[0] != '/') {
433 DOS_GetCurrDir_Unix(temp
+strlen(temp
), drive
);
435 strcat(temp
, dostemp
);
436 DOS_SimplifyPath(temp
);
438 dprintf_dosfs(stddeb
,"GetUnixFileName: %s => %s\n", dosfilename
, temp
);
442 /* Note: This function works on directories as well as long as
443 * the directory ends in a slash.
445 char *DOS_GetDosFileName(char *unixfilename
)
448 static char temp
[256], temp2
[256];
449 /* /dos/windows/system.ini => c:\windows\system.ini */
451 dprintf_dosfs(stddeb
,"DOS_GetDosFileName: %s\n", unixfilename
);
452 if (unixfilename
[0] == '/') {
453 strncpy(temp
, unixfilename
, 255);
456 /* Expand it if it's a relative name. */
458 if(strncmp(unixfilename
, "./", 2) != 0) {
459 strcat(temp
, unixfilename
+ 1);
462 strcat(temp
, unixfilename
);
465 for (i
= 0 ; i
< MAX_DOS_DRIVES
; i
++) {
466 if (DosDrives
[i
].rootdir
!= NULL
) {
467 int len
= strlen(DosDrives
[i
].rootdir
);
468 dprintf_dosfs(stddeb
, " check %c:%s\n", i
+'A', DosDrives
[i
].rootdir
);
469 if (strncmp(DosDrives
[i
].rootdir
, temp
, len
) == 0 && temp
[len
] == '/')
471 sprintf(temp2
, "%c:%s", 'A' + i
, temp
+len
);
477 sprintf(temp
, "Z:%s", unixfilename
);
482 int DOS_ValidDirectory(int drive
, char *name
)
487 strcpy(temp
, DosDrives
[drive
].rootdir
);
489 if (stat(temp
, &s
)) return 0;
490 if (!S_ISDIR(s
.st_mode
)) return 0;
491 dprintf_dosfs(stddeb
, "==> OK\n");
495 int DOS_GetDefaultDrive(void)
497 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
498 int drive
= pTask
== NULL
? CurrentDrive
: pTask
->curdrive
& ~0x80;
500 dprintf_dosfs(stddeb
,"GetDefaultDrive (%c)\n",'A'+drive
);
504 void DOS_SetDefaultDrive(int drive
)
506 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
508 dprintf_dosfs(stddeb
,"SetDefaultDrive to %c:\n",'A'+drive
);
509 if (DOS_ValidDrive(drive
) && drive
!= DOS_GetDefaultDrive()) {
510 if (pTask
== NULL
) CurrentDrive
= drive
;
513 pTask
->curdrive
= drive
| 0x80;
514 strcpy(temp
, DosDrives
[drive
].rootdir
);
515 strcat(temp
, DosDrives
[drive
].cwd
);
516 strcpy(temp
, DOS_GetDosFileName(temp
));
517 dprintf_dosfs(stddeb
, " curdir = %s\n", temp
);
518 if (strlen(temp
)-2 < sizeof(pTask
->curdir
)) strcpy(pTask
->curdir
, temp
+2);
519 else fprintf(stderr
, "dosfs: curdir too long\n");
524 int DOS_DisableDrive(int drive
)
526 if (drive
>= MAX_DOS_DRIVES
) return 0;
527 if (DosDrives
[drive
].rootdir
== NULL
) return 0;
529 DosDrives
[drive
].disabled
= 1;
533 int DOS_EnableDrive(int drive
)
535 if (drive
>= MAX_DOS_DRIVES
) return 0;
536 if (DosDrives
[drive
].rootdir
== NULL
) return 0;
538 DosDrives
[drive
].disabled
= 0;
542 int DOS_ChangeDir(int drive
, char *dirname
)
544 TDB
*pTask
= (TDB
*)GlobalLock(GetCurrentTask());
547 if (!DOS_ValidDrive(drive
)) return 0;
549 if (dirname
[0] == '\\') {
550 strcpy(temp
, dirname
);
552 DOS_GetCurrDir_Unix(temp
, drive
);
553 strcat(temp
, dirname
);
557 DOS_SimplifyPath(temp
);
558 dprintf_dosfs(stddeb
,"DOS_SetCWD: %c: %s ==> %s\n", 'A'+drive
, dirname
, temp
);
560 if (!DOS_ValidDirectory(drive
, temp
)) return 0;
561 strcpy(DosDrives
[drive
].cwd
, temp
);
562 if (pTask
!= NULL
&& DOS_GetDefaultDrive() == drive
) {
563 strcpy(temp
, DosDrives
[drive
].rootdir
);
564 strcat(temp
, DosDrives
[drive
].cwd
);
565 strcpy(temp
, DOS_GetDosFileName(temp
));
566 dprintf_dosfs(stddeb
, " curdir = %s\n", temp
);
567 if (strlen(temp
)-2 < sizeof(pTask
->curdir
)) strcpy(pTask
->curdir
, temp
+2);
568 else fprintf(stderr
, "dosfs: curdir too long\n");
573 int DOS_MakeDir(int drive
, char *dirname
)
575 char temp
[256], currdir
[256];
577 if (!DOS_ValidDrive(drive
)) return 0;
579 strcpy(temp
, DosDrives
[drive
].rootdir
);
580 DOS_GetCurrDir_Unix(currdir
, drive
);
581 strcat(temp
, currdir
);
582 strcat(temp
, dirname
);
584 DOS_SimplifyPath(temp
);
587 dprintf_dosfs(stddeb
, "DOS_MakeDir: %c:\%s => %s",'A'+drive
, dirname
, temp
);
591 int DOS_GetSerialNumber(int drive
, unsigned long *serialnumber
)
593 if (!DOS_ValidDrive(drive
))
596 *serialnumber
= DosDrives
[drive
].serialnumber
;
600 int DOS_SetSerialNumber(int drive
, unsigned long serialnumber
)
602 if (!DOS_ValidDrive(drive
))
605 DosDrives
[drive
].serialnumber
= serialnumber
;
609 char *DOS_GetVolumeLabel(int drive
)
611 if (!DOS_ValidDrive(drive
))
614 return DosDrives
[drive
].label
;
617 int DOS_SetVolumeLabel(int drive
, char *label
)
619 if (!DOS_ValidDrive(drive
))
622 strncpy(DosDrives
[drive
].label
, label
, 8);
626 int DOS_GetFreeSpace(int drive
, long *size
, long *available
)
630 if (!DOS_ValidDrive(drive
))
634 if (statfs(DosDrives
[drive
].rootdir
, &info
, 0, 0) < 0) {
636 if (statfs(DosDrives
[drive
].rootdir
, &info
) < 0) {
638 fprintf(stderr
,"dosfs: cannot do statfs(%s)\n",
639 DosDrives
[drive
].rootdir
);
643 *size
= info
.f_bsize
* info
.f_blocks
;
645 *available
= info
.f_bfree
* info
.f_bsize
;
647 *available
= info
.f_bavail
* info
.f_bsize
;
653 char *DOS_FindFile(char *buffer
, int buflen
, const char *filename
, char **extensions
,
656 char *workingpath
, *dirname
, *rootname
, **e
;
660 struct stat filestat
;
662 if (strchr(filename
, '\\') != NULL
)
664 strncpy(buffer
, DOS_GetUnixFileName(filename
), buflen
);
665 stat( buffer
, &filestat
);
666 if (S_ISREG(filestat
.st_mode
))
672 if (strchr(filename
, '/') != NULL
)
674 strncpy(buffer
, filename
, buflen
);
678 dprintf_dosfs(stddeb
,"DOS_FindFile: looking for %s\n", filename
);
679 rootnamelen
= strlen(filename
);
680 rootname
= strdup(filename
);
682 workingpath
= strdup(path
);
684 for(dirname
= strtok(workingpath
, ";");
686 dirname
= strtok(NULL
, ";"))
688 if (strchr(dirname
, '\\') != NULL
)
689 d
= opendir( DOS_GetUnixFileName(dirname
) );
691 d
= opendir( dirname
);
693 dprintf_dosfs(stddeb
,"in %s\n",dirname
);
696 while ((f
= readdir(d
)) != NULL
)
698 if (strcasecmp(rootname
, f
->d_name
) != 0) {
699 if (strncasecmp(rootname
, f
->d_name
, rootnamelen
) != 0
700 || extensions
== NULL
701 || f
->d_name
[rootnamelen
] != '.')
704 for (e
= extensions
; *e
!= NULL
; e
++) {
705 if (strcasecmp(*e
, f
->d_name
+ rootnamelen
+ 1) == 0)
708 if (*e
== NULL
) continue;
711 if (strchr(dirname
, '\\') != NULL
) {
712 strncpy(buffer
, DOS_GetUnixFileName(dirname
), buflen
);
714 strncpy(buffer
, dirname
, buflen
);
717 strncat(buffer
, "/", buflen
- strlen(buffer
));
718 strncat(buffer
, f
->d_name
, buflen
- strlen(buffer
));
720 stat(buffer
, &filestat
);
721 if (S_ISREG(filestat
.st_mode
)) {
724 DOS_SimplifyPath(buffer
);
734 /**********************************************************************
737 char *WineIniFileName(void)
740 static char *filename
= NULL
;
741 static char name
[256];
746 strcpy(name
, WINE_INI_USER
);
747 ExpandTildeString(name
);
748 if ((fd
= open(name
, O_RDONLY
)) != -1) {
753 if ((fd
= open(WINE_INI_GLOBAL
, O_RDONLY
)) != -1) {
755 filename
= WINE_INI_GLOBAL
;
758 fprintf(stderr
,"wine: can't open configuration file %s or %s !\n",
759 WINE_INI_GLOBAL
, WINE_INI_USER
);
763 char *WinIniFileName(void)
765 static char *name
= NULL
;
770 name
= xmalloc(1024);
772 strcpy(name
, DOS_GetUnixFileName(WindowsDirectory
));
774 strcat(name
, "win.ini");
776 name
= xrealloc(name
, strlen(name
) + 1);
781 static int match(char *filename
, char *filemask
)
783 char name
[12], mask
[12];
786 dprintf_dosfs(stddeb
, "match: %s, %s\n", filename
, filemask
);
788 for( i
=0; i
<11; i
++ ) {
796 if( !(*filename
) || *filename
== '.' )
799 name
[i
] = toupper( *filename
++ );
800 while( *filename
&& *filename
!= '.' )
804 for( i
=8; i
<11; i
++ )
808 name
[i
] = toupper( *filename
++ );
811 if( !(*filemask
) || *filemask
== '.' )
813 else if( *filemask
== '*' ) {
820 mask
[i
] = toupper( *filemask
++ );
821 while( *filemask
&& *filemask
!= '.' )
825 for( i
=8; i
<11; i
++ )
828 else if (*filemask
== '*' ) {
830 for( j
=i
; j
<11; j
++ )
835 mask
[i
] = toupper( *filemask
++ );
837 dprintf_dosfs(stddeb
, "changed to: %s, %s\n", name
, mask
);
839 for( i
=0; i
<11; i
++ )
840 if( ( name
[i
] != mask
[i
] ) && ( mask
[i
] != '?' ) )
846 struct dosdirent
*DOS_opendir(char *dosdirname
)
853 if ((unixdirname
= DOS_GetUnixFileName(dosdirname
)) == NULL
) return NULL
;
855 len
= strrchr(unixdirname
, '/') - unixdirname
+ 1;
856 strncpy(dirname
, unixdirname
, len
);
858 unixdirname
= strrchr(unixdirname
, '/') + 1;
860 for (x
=0; x
<= max_open_dirs
; x
++) {
861 if (x
== max_open_dirs
) {
863 DosDirs
=(struct dosdirent
*)xrealloc(DosDirs
,(++max_open_dirs
)*sizeof(DosDirs
[0]));
865 DosDirs
=(struct dosdirent
*)xmalloc(sizeof(DosDirs
[0]));
868 break; /* this one is definitely not in use */
870 if (!DosDirs
[x
].inuse
) break;
871 if (strcmp(DosDirs
[x
].unixpath
, dirname
) == 0) break;
874 strncpy(DosDirs
[x
].filemask
, unixdirname
, 12);
875 DosDirs
[x
].filemask
[12] = 0;
876 dprintf_dosfs(stddeb
,"DOS_opendir: %s / %s\n", unixdirname
, dirname
);
878 DosDirs
[x
].inuse
= 1;
879 strcpy(DosDirs
[x
].unixpath
, dirname
);
880 DosDirs
[x
].entnum
= 0;
882 if ((ds
= opendir(dirname
)) == NULL
) return NULL
;
883 if (-1==(DosDirs
[x
].telldirnum
=telldir(ds
))) {
887 if (-1==closedir(ds
)) return NULL
;
893 struct dosdirent
*DOS_readdir(struct dosdirent
*de
)
902 if (!(ds
=opendir(de
->unixpath
))) return NULL
;
903 seekdir(ds
,de
->telldirnum
); /* returns no error value. strange */
905 if (de
->search_attribute
& FA_LABEL
) {
907 de
->search_attribute
&= ~FA_LABEL
; /* don't find it again */
908 for(drive
= 0; drive
< MAX_DOS_DRIVES
; drive
++) {
909 if (DosDrives
[drive
].rootdir
!= NULL
&&
910 strcmp(DosDrives
[drive
].rootdir
, de
->unixpath
) == 0)
912 strcpy(de
->filename
, DOS_GetVolumeLabel(drive
));
913 de
->attribute
= FA_LABEL
;
920 if ((d
= readdir(ds
)) == NULL
) {
921 de
->telldirnum
=telldir(ds
);
926 de
->entnum
++; /* Increment the directory entry number */
927 strcpy(de
->filename
, d
->d_name
);
928 if (d
->d_reclen
> 12)
929 de
->filename
[12] = '\0';
932 } while ( !match(de
->filename
, de
->filemask
) );
934 strcpy(temp
,de
->unixpath
);
936 strcat(temp
,de
->filename
);
937 ToUnix(temp
+ strlen(de
->unixpath
));
941 if S_ISDIR(st
.st_mode
)
942 de
->attribute
|= FA_DIREC
;
944 de
->filesize
= st
.st_size
;
945 de
->filetime
= st
.st_mtime
;
947 de
->telldirnum
= telldir(ds
);
952 void DOS_closedir(struct dosdirent
*de
)
958 char *DOS_GetRedirectedDir(int drive
)
960 if(DOS_ValidDrive(drive
))
961 return (DosDrives
[drive
].rootdir
);