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@(trashcan.)hacktic.nl
9 * - removed ParseDosFileName, and DosDrive structures.
10 * - structures dynamically configured at runtime.
11 * - _lopen modified to use GetUnixFileName.
13 * DEC 93 Erik Bos (erik@(trashcan.)hacktic.nl)
14 * - Existing functions modified to use dosfs functions.
15 * - Added _llseek, _lcreat, GetDriveType, GetTempDrive,
16 * GetWindowsDirectory, GetSystemDirectory, GetTempFileName.
18 ************************************************************************/
27 #include "prototypes.h"
32 #include "registers.h"
35 /* #define DEBUG_FILE /* */
36 /* #undef DEBUG_FILE /* */
41 char WindowsDirectory
[256], SystemDirectory
[256], TempDirectory
[256];
42 extern char WindowsPath
[256];
44 extern char WindowsPath
[];
45 extern WORD ExtendedError
;
48 char *GetDosFileName(char *unixfilename
);
50 /***************************************************************************
53 Emulate the _lopen windows call
54 ***************************************************************************/
55 INT
_lopen (LPSTR lpPathName
, INT iReadWrite
)
60 dprintf_file(stddeb
, "_lopen: open('%s', %X);\n", lpPathName
, iReadWrite
);
61 if ((UnixFileName
= GetUnixFileName(lpPathName
)) == NULL
)
64 handle
= open (UnixFileName
, iReadWrite
);
66 dprintf_file(stddeb
, "_lopen: open: %s (handle %d)\n", UnixFileName
, handle
);
74 /***************************************************************************
76 ***************************************************************************/
77 INT
_lread (INT hFile
, LPSTR lpBuffer
, WORD wBytes
)
81 dprintf_file(stddeb
, "_lread: handle %d, buffer = %ld, length = %d\n",
82 hFile
, (int) lpBuffer
, wBytes
);
84 result
= read (hFile
, lpBuffer
, wBytes
);
92 /****************************************************************************
94 ****************************************************************************/
95 INT
_lwrite (INT hFile
, LPSTR lpBuffer
, WORD wBytes
)
99 dprintf_file(stddeb
, "_lwrite: handle %d, buffer = %ld, length = %d\n",
100 hFile
, (int) lpBuffer
, wBytes
);
102 result
= write (hFile
, lpBuffer
, wBytes
);
110 /***************************************************************************
112 ***************************************************************************/
113 INT
_lclose (INT hFile
)
115 dprintf_file(stddeb
, "_lclose: handle %d\n", hFile
);
122 /**************************************************************************
124 **************************************************************************/
125 INT
OpenFile (LPSTR lpFileName
, LPOFSTRUCT ofs
, WORD wStyle
)
129 struct sigcontext_struct ccontext
;
130 /* To make macros like EAX happy */
131 struct sigcontext_struct
*context
=&ccontext
;
133 char filename
[MAX_PATH
+1];
140 dprintf_file(stddeb
,"Openfile(%s,<struct>,%d) ",lpFileName
,wStyle
);
142 action
= wStyle
& 0xff00;
145 /* OF_CREATE is completly different from all other options, so
148 if (action
& OF_CREATE
)
153 if (!(action
& OF_REOPEN
))
154 strcpy(ofs
->szPathName
, lpFileName
);
155 ofs
->cBytes
= sizeof(OFSTRUCT
);
156 ofs
->fFixedDisk
= FALSE
;
158 *((int*)ofs
->reserved
) = 0;
160 if ((unixfilename
= GetUnixFileName (ofs
->szPathName
)) == NULL
)
163 ofs
->nErrCode
= ExtendedError
;
166 handle
= open (unixfilename
, (wStyle
& 0x0003) | O_CREAT
, 0x666);
170 ofs
->nErrCode
= ExtendedError
;
176 /* If path isn't given, try to find the file. */
178 if (!(action
& OF_REOPEN
))
180 if( !( index(lpFileName
,'\\') || index(lpFileName
,'/') ||
181 index(lpFileName
,':')))
184 char temp
[MAX_PATH
+1];
185 strcpy (filename
, lpFileName
);
186 if ( (!stat(GetUnixFileName(filename
), &s
)) && (S_ISREG(s
.st_mode
)) )
188 GetWindowsDirectory (filename
,MAX_PATH
);
189 if ((!filename
[0])||(filename
[strlen(filename
)-1]!='\\'))
190 strcat(filename
, "\\");
191 strcat (filename
, lpFileName
);
192 if ( (!stat(GetUnixFileName(filename
), &s
)) && (S_ISREG(s
.st_mode
)) )
194 GetSystemDirectory (filename
,MAX_PATH
);
195 if ((!filename
[0])||(filename
[strlen(filename
)-1]!='\\'))
196 strcat(filename
, "\\");
197 strcat (filename
, lpFileName
);
198 if ( (!stat(GetUnixFileName(filename
), &s
)) && (S_ISREG(s
.st_mode
)) )
200 if (!FindFile(temp
,MAX_PATH
,lpFileName
,NULL
,WindowsPath
))
202 strcpy(filename
, GetDosFileName(temp
));
205 strcpy (filename
, lpFileName
);
209 strcpy (filename
,lpFileName
);
211 ofs
->cBytes
= sizeof(OFSTRUCT
);
212 ofs
->fFixedDisk
= FALSE
;
213 strcpy(ofs
->szPathName
, filename
);
215 if (!(action
& OF_VERIFY
))
216 *((int*)ofs
->reserved
) = 0;
220 if (action
& OF_PARSE
)
223 if (action
& OF_DELETE
)
224 return unlink(ofs
->szPathName
);
227 /* Now on to getting some information about that file */
229 if (res
= stat(GetUnixFileName(ofs
->szPathName
), &s
))
232 ofs
->nErrCode
= ExtendedError
;
236 now
= localtime (&s
.st_mtime
);
238 if (action
& OF_VERIFY
)
239 verify_time
= *((int*)ofs
->reserved
);
241 *((WORD
*)(&ofs
->reserved
[2]))=
242 ((now
->tm_hour
* 0x2000) + (now
->tm_min
* 0x20) + (now
->tm_sec
/ 2));
243 *((WORD
*)(&ofs
->reserved
[0]))=
244 ((now
->tm_year
* 0x200) + (now
->tm_mon
* 0x20) + now
->tm_mday
);
246 if (action
& OF_EXIST
)
249 if (action
& OF_VERIFY
)
250 return (verify_time
!= *((int*)ofs
->reserved
));
253 /* Now we are actually going to open the file. According to Microsoft's
254 Knowledge Basis, this is done by calling int 21h, ax=3dh. */
257 AL
= (AL
& 0x0f) | (wStyle
& 0x70); /* Handle OF_SHARE_xxx etc. */
258 AL
= (AL
& 0xf0) | (wStyle
& 0x03); /* Handle OF_READ etc. */
259 DS
= segment (ofs
->szPathName
);
260 DX
= offset (ofs
->szPathName
);
262 OpenExistingFile (context
);
264 if (EFL
& 0x00000001) /* Cflag */
273 /**************************************************************************
276 Changes the number of file handles available to the application. Since
277 Linux isn't limited to 20 files, this one's easy. - SL
278 **************************************************************************/
280 #if !defined (OPEN_MAX)
281 /* This one is for the Sun */
282 #define OPEN_MAX _POSIX_OPEN_MAX
284 WORD
SetHandleCount (WORD wNumber
)
286 dprintf_file(stddeb
,"SetHandleCount(%d)\n",wNumber
);
287 return((wNumber
<OPEN_MAX
) ? wNumber
: OPEN_MAX
);
290 /***************************************************************************
292 ***************************************************************************/
293 LONG
_llseek (INT hFile
, LONG lOffset
, INT nOrigin
)
297 dprintf_file(stddeb
, "_llseek: handle %d, offset %ld, origin %d\n",
298 hFile
, lOffset
, nOrigin
);
301 case 1: origin
= SEEK_CUR
;
303 case 2: origin
= SEEK_END
;
305 default: origin
= SEEK_SET
;
309 return ( lseek(hFile
, lOffset
, origin
) );
312 /***************************************************************************
314 ***************************************************************************/
315 INT
_lcreat (LPSTR lpszFilename
, INT fnAttribute
)
320 dprintf_file(stddeb
, "_lcreat: filename %s, attributes %d\n",
321 lpszFilename
, fnAttribute
);
322 if ((UnixFileName
= GetUnixFileName(lpszFilename
)) == NULL
)
324 handle
= open (UnixFileName
, O_CREAT
| O_TRUNC
| O_WRONLY
, 426);
332 /***************************************************************************
334 ***************************************************************************/
335 UINT
GetDriveType(INT drive
)
338 dprintf_file(stddeb
,"GetDriveType %c:\n",'A'+drive
);
340 if (!DOS_ValidDrive(drive
))
341 return DRIVE_DOESNOTEXIST
;
343 if (drive
== 0 || drive
== 1)
344 return DRIVE_REMOVABLE
;
349 /***************************************************************************
351 ***************************************************************************/
352 BYTE
GetTempDrive(BYTE chDriveLetter
)
354 dprintf_file(stddeb
,"GetTempDrive (%d)\n",chDriveLetter
);
358 /***************************************************************************
360 ***************************************************************************/
361 UINT
GetWindowsDirectory(LPSTR lpszSysPath
, UINT cbSysPath
)
363 if (cbSysPath
< strlen(WindowsDirectory
))
366 strcpy(lpszSysPath
, WindowsDirectory
);
368 dprintf_file(stddeb
,"GetWindowsDirectory (%s)\n",lpszSysPath
);
370 ChopOffSlash(lpszSysPath
);
371 return(strlen(lpszSysPath
));
373 /***************************************************************************
375 ***************************************************************************/
376 UINT
GetSystemDirectory(LPSTR lpszSysPath
, UINT cbSysPath
)
378 if (cbSysPath
< strlen(SystemDirectory
))
381 strcpy(lpszSysPath
, SystemDirectory
);
383 dprintf_file(stddeb
,"GetSystemDirectory (%s)\n",lpszSysPath
);
385 ChopOffSlash(lpszSysPath
);
386 return(strlen(lpszSysPath
));
388 /***************************************************************************
390 ***************************************************************************/
391 INT
GetTempFileName(BYTE bDriveLetter
, LPCSTR lpszPrefixString
, UINT uUnique
, LPSTR lpszTempFileName
)
398 unique
= time(NULL
)%99999L;
400 unique
= uUnique
%99999L;
402 strcpy(tempname
,lpszPrefixString
);
405 sprintf(lpszTempFileName
,"%s\\%s%d.tmp", TempDirectory
, tempname
,
408 ToDos(lpszTempFileName
);
410 dprintf_file(stddeb
,"GetTempFilename: %c %s %d => %s\n",bDriveLetter
,
411 lpszPrefixString
,uUnique
,lpszTempFileName
);
412 if ((handle
= _lcreat (lpszTempFileName
, 0x0000)) == -1) {
413 fprintf(stderr
,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName
);
421 /***************************************************************************
423 ***************************************************************************/
424 WORD
SetErrorMode(WORD x
)
426 dprintf_file(stdnimp
,"wine: SetErrorMode %4x (ignored)\n",x
);
429 /***************************************************************************
431 ***************************************************************************/
432 long _hread(int hf
, void FAR
*hpvBuffer
, long cbBuffer
)
434 return read(hf
, hpvBuffer
, cbBuffer
);
436 /***************************************************************************
438 ***************************************************************************/
439 long _hwrite(int hf
, const void FAR
*hpvBuffer
, long cbBuffer
)
441 return write(hf
, hpvBuffer
, cbBuffer
);