1 /************************************************************************
2 * FILE.C Copyright (C) 1993 John Burton
4 * File I/O routines for the Linux Wine Project.
6 * WARNING : Many options of OpenFile are not yet implemeted.
8 * NOV 93 Erik Bos (erik@xs4all.nl)
9 * - removed ParseDosFileName, and DosDrive structures.
10 * - structures dynamically configured at runtime.
11 * - _lopen modified to use DOS_GetUnixFileName.
12 * - Existing functions modified to use dosfs functions.
13 * - Added _llseek, _lcreat, GetDriveType, GetTempDrive,
14 * GetWindowsDirectory, GetSystemDirectory, GetTempFileName.
16 ************************************************************************/
30 #include "registers.h"
37 char WindowsDirectory
[256], SystemDirectory
[256], TempDirectory
[256];
39 /***************************************************************************
42 Emulate the _lopen windows call
43 ***************************************************************************/
44 INT
_lopen (LPSTR lpPathName
, INT iReadWrite
)
49 dprintf_file(stddeb
, "_lopen: open('%s', %X);\n", lpPathName
, iReadWrite
);
50 if ((UnixFileName
= DOS_GetUnixFileName(lpPathName
)) == NULL
)
53 handle
= open (UnixFileName
, iReadWrite
);
54 if( ( handle
== -1 ) && Options
.allowReadOnly
)
55 handle
= open( UnixFileName
, O_RDONLY
);
57 dprintf_file(stddeb
, "_lopen: open: %s (handle %d)\n", UnixFileName
, handle
);
65 /***************************************************************************
67 ***************************************************************************/
68 INT
_lread (INT hFile
, LPSTR lpBuffer
, WORD wBytes
)
72 dprintf_file(stddeb
, "_lread: handle %d, buffer = %ld, length = %d\n",
73 hFile
, (long) lpBuffer
, wBytes
);
75 result
= read (hFile
, lpBuffer
, wBytes
);
83 /****************************************************************************
85 ****************************************************************************/
86 INT
_lwrite (INT hFile
, LPSTR lpBuffer
, WORD wBytes
)
90 dprintf_file(stddeb
, "_lwrite: handle %d, buffer = %ld, length = %d\n",
91 hFile
, (long) lpBuffer
, wBytes
);
93 result
= write (hFile
, lpBuffer
, wBytes
);
101 /***************************************************************************
103 ***************************************************************************/
104 INT
_lclose (INT hFile
)
106 dprintf_file(stddeb
, "_lclose: handle %d\n", hFile
);
113 /**************************************************************************
115 **************************************************************************/
116 INT
OpenFile (LPSTR lpFileName
, LPOFSTRUCT ofs
, WORD wStyle
)
119 dprintf_file(stdnimp
, "OpenFile: not implemented\n");
122 struct sigcontext_struct ccontext
;
123 /* To make macros like EAX happy */
124 struct sigcontext_struct
*context
=&ccontext
;
126 char filename
[MAX_PATH
+1];
133 dprintf_file(stddeb
,"Openfile(%s,<struct>,%d) ",lpFileName
,wStyle
);
135 action
= wStyle
& 0xff00;
138 /* OF_CREATE is completly different from all other options, so
141 if (action
& OF_CREATE
)
146 if (!(action
& OF_REOPEN
))
147 strcpy(ofs
->szPathName
, lpFileName
);
148 ofs
->cBytes
= sizeof(OFSTRUCT
);
149 ofs
->fFixedDisk
= FALSE
;
151 *((int*)ofs
->reserved
) = 0;
153 if ((unixfilename
= DOS_GetUnixFileName (ofs
->szPathName
)) == NULL
)
156 ofs
->nErrCode
= ExtendedError
;
159 handle
= open (unixfilename
, (wStyle
& 0x0003) | O_CREAT
, 0x666);
163 ofs
->nErrCode
= ExtendedError
;
169 /* If path isn't given, try to find the file. */
171 if (!(action
& OF_REOPEN
))
173 if( !( index(lpFileName
,'\\') || index(lpFileName
,'/') ||
174 index(lpFileName
,':')))
177 char temp
[MAX_PATH
+1];
178 strcpy (filename
, lpFileName
);
179 if ( (!stat(DOS_GetUnixFileName(filename
), &s
)) && (S_ISREG(s
.st_mode
)) )
181 GetWindowsDirectory (filename
,MAX_PATH
);
182 if ((!filename
[0])||(filename
[strlen(filename
)-1]!='\\'))
183 strcat(filename
, "\\");
184 strcat (filename
, lpFileName
);
185 if ( (!stat(DOS_GetUnixFileName(filename
), &s
)) && (S_ISREG(s
.st_mode
)) )
187 GetSystemDirectory (filename
,MAX_PATH
);
188 if ((!filename
[0])||(filename
[strlen(filename
)-1]!='\\'))
189 strcat(filename
, "\\");
190 strcat (filename
, lpFileName
);
191 if ( (!stat(DOS_GetUnixFileName(filename
), &s
)) && (S_ISREG(s
.st_mode
)) )
193 if (!DOS_FindFile(temp
,MAX_PATH
,lpFileName
,NULL
,WindowsPath
))
195 strcpy(filename
, DOS_GetDosFileName(temp
));
198 strcpy (filename
, lpFileName
);
202 strcpy (filename
,lpFileName
);
204 ofs
->cBytes
= sizeof(OFSTRUCT
);
205 ofs
->fFixedDisk
= FALSE
;
206 strcpy(ofs
->szPathName
, filename
);
208 if (!(action
& OF_VERIFY
))
209 *((int*)ofs
->reserved
) = 0;
213 if (action
& OF_PARSE
)
216 if (action
& OF_DELETE
)
217 return unlink(ofs
->szPathName
);
220 /* Now on to getting some information about that file */
222 if ((res
= stat(DOS_GetUnixFileName(ofs
->szPathName
), &s
)))
225 ofs
->nErrCode
= ExtendedError
;
229 now
= localtime (&s
.st_mtime
);
231 if (action
& OF_VERIFY
)
232 verify_time
= *((int*)ofs
->reserved
);
234 *((WORD
*)(&ofs
->reserved
[2]))=
235 ((now
->tm_hour
* 0x2000) + (now
->tm_min
* 0x20) + (now
->tm_sec
/ 2));
236 *((WORD
*)(&ofs
->reserved
[0]))=
237 ((now
->tm_year
* 0x200) + (now
->tm_mon
* 0x20) + now
->tm_mday
);
240 if (action
& OF_VERIFY
)
241 return (verify_time
!= *((int*)ofs
->reserved
));
243 if (action
& OF_EXIST
)
246 /* Now we are actually going to open the file. According to Microsoft's
247 Knowledge Basis, this is done by calling int 21h, ax=3dh. */
251 AL
= (AL
& 0x0f) | (wStyle
& 0x70); /* Handle OF_SHARE_xxx etc. */
252 AL
= (AL
& 0xf0) | (wStyle
& 0x03); /* Handle OF_READ etc. */
253 DS
= SELECTOROF(ofs
->szPathName
);
254 DX
= OFFSETOF(ofs
->szPathName
);
256 OpenExistingFile (context
);
258 if (EFL
& 0x00000001) /* Cflag */
266 /* FIXME: Quick hack to get it to work without calling DOS --AJ */
271 case 0: mode
= O_RDONLY
; break;
272 case 1: mode
= O_WRONLY
; break;
273 default: mode
= O_RDWR
; break;
275 if ((handle
= open(DOS_GetUnixFileName(ofs
->szPathName
), mode
)) == -1)
277 ofs
->nErrCode
= 2; /* not found */
280 /* don't bother with locking for now */
287 /**************************************************************************
290 Changes the number of file handles available to the application. Since
291 Linux isn't limited to 20 files, this one's easy. - SL
292 **************************************************************************/
294 #if !defined (OPEN_MAX)
295 /* This one is for the Sun */
296 #define OPEN_MAX _POSIX_OPEN_MAX
298 WORD
SetHandleCount (WORD wNumber
)
300 dprintf_file(stddeb
,"SetHandleCount(%d)\n",wNumber
);
301 return((wNumber
<OPEN_MAX
) ? wNumber
: OPEN_MAX
);
304 /***************************************************************************
306 ***************************************************************************/
307 LONG
_llseek (INT hFile
, LONG lOffset
, INT nOrigin
)
311 dprintf_file(stddeb
, "_llseek: handle %d, offset %ld, origin %d\n",
312 hFile
, lOffset
, nOrigin
);
315 case 1: origin
= SEEK_CUR
;
317 case 2: origin
= SEEK_END
;
319 default: origin
= SEEK_SET
;
323 return ( lseek(hFile
, lOffset
, origin
) );
326 /***************************************************************************
328 ***************************************************************************/
329 INT
_lcreat (LPSTR lpszFilename
, INT fnAttribute
)
334 dprintf_file(stddeb
, "_lcreat: filename %s, attributes %d\n",
335 lpszFilename
, fnAttribute
);
336 if ((UnixFileName
= DOS_GetUnixFileName(lpszFilename
)) == NULL
)
338 handle
= open (UnixFileName
, O_CREAT
| O_TRUNC
| O_WRONLY
, 426);
346 /***************************************************************************
348 ***************************************************************************/
349 UINT
GetDriveType(INT drive
)
352 dprintf_file(stddeb
,"GetDriveType %c:\n",'A'+drive
);
354 if (!DOS_ValidDrive(drive
))
355 return DRIVE_DOESNOTEXIST
;
357 if (drive
== 0 || drive
== 1)
358 return DRIVE_REMOVABLE
;
363 /***************************************************************************
365 ***************************************************************************/
366 BYTE
GetTempDrive(BYTE chDriveLetter
)
368 dprintf_file(stddeb
,"GetTempDrive (%d)\n",chDriveLetter
);
372 /***************************************************************************
374 ***************************************************************************/
375 UINT
GetWindowsDirectory(LPSTR lpszSysPath
, UINT cbSysPath
)
377 if (cbSysPath
< strlen(WindowsDirectory
))
380 strcpy(lpszSysPath
, WindowsDirectory
);
382 dprintf_file(stddeb
,"GetWindowsDirectory (%s)\n",lpszSysPath
);
384 ChopOffSlash(lpszSysPath
);
385 return(strlen(lpszSysPath
));
387 /***************************************************************************
389 ***************************************************************************/
390 UINT
GetSystemDirectory(LPSTR lpszSysPath
, UINT cbSysPath
)
392 if (cbSysPath
< strlen(SystemDirectory
))
395 strcpy(lpszSysPath
, SystemDirectory
);
397 dprintf_file(stddeb
,"GetSystemDirectory (%s)\n",lpszSysPath
);
399 ChopOffSlash(lpszSysPath
);
400 return(strlen(lpszSysPath
));
402 /***************************************************************************
404 ***************************************************************************/
405 INT
GetTempFileName(BYTE bDriveLetter
, LPCSTR lpszPrefixString
, UINT uUnique
, LPSTR lpszTempFileName
)
412 unique
= time(NULL
)%99999L;
414 unique
= uUnique
%99999L;
416 strcpy(tempname
,lpszPrefixString
);
419 sprintf(lpszTempFileName
,"%s\\%s%d.tmp", TempDirectory
, tempname
,
422 ToDos(lpszTempFileName
);
424 dprintf_file(stddeb
,"GetTempFilename: %c %s %d => %s\n",bDriveLetter
,
425 lpszPrefixString
,uUnique
,lpszTempFileName
);
426 if ((handle
= _lcreat (lpszTempFileName
, 0x0000)) == -1) {
427 fprintf(stderr
,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName
);
435 /***************************************************************************
437 ***************************************************************************/
438 WORD
SetErrorMode(WORD x
)
440 dprintf_file(stdnimp
,"wine: SetErrorMode %4x (ignored)\n",x
);
445 /***************************************************************************
447 ***************************************************************************/
448 long _hread(int hf
, void FAR
*hpvBuffer
, long cbBuffer
)
450 return read(hf
, hpvBuffer
, cbBuffer
);
452 /***************************************************************************
454 ***************************************************************************/
455 long _hwrite(int hf
, const void FAR
*hpvBuffer
, long cbBuffer
)
457 return write(hf
, hpvBuffer
, cbBuffer
);