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 ************************************************************************/
34 char WindowsDirectory
[256], SystemDirectory
[256], TempDirectory
[256];
36 /***************************************************************************
39 Emulate the _lopen windows call
40 ***************************************************************************/
41 INT
_lopen (LPSTR lpPathName
, INT iReadWrite
)
47 dprintf_file(stddeb
, "_lopen: open('%s', %X);\n", lpPathName
, iReadWrite
);
48 if ((UnixFileName
= DOS_GetUnixFileName(lpPathName
)) == NULL
)
50 switch(iReadWrite
& 3)
52 case OF_READ
: mode
= O_RDONLY
; break;
53 case OF_WRITE
: mode
= O_WRONLY
; break;
54 case OF_READWRITE
: mode
= O_RDWR
; break;
56 handle
= open( UnixFileName
, mode
);
57 if (( handle
== -1 ) && Options
.allowReadOnly
)
58 handle
= open( UnixFileName
, O_RDONLY
);
60 dprintf_file(stddeb
, "_lopen: open: %s (handle %d)\n", UnixFileName
, handle
);
68 /***************************************************************************
70 ***************************************************************************/
71 INT
_lread (INT hFile
, LPSTR lpBuffer
, WORD wBytes
)
75 dprintf_file(stddeb
, "_lread: handle %d, buffer = %p, length = %d\n",
76 hFile
, lpBuffer
, wBytes
);
78 result
= (wBytes
== 0) ? 0 : read (hFile
, lpBuffer
, wBytes
);
86 /****************************************************************************
88 ****************************************************************************/
89 INT
_lwrite (INT hFile
, LPCSTR lpBuffer
, WORD wBytes
)
93 dprintf_file(stddeb
, "_lwrite: handle %d, buffer = %p, length = %d\n",
94 hFile
, lpBuffer
, wBytes
);
96 if(wBytes
== 0) { /* Expand the file size if necessary */
100 prev
= lseek(hFile
, 0, SEEK_CUR
);
101 if(prev
== -1) return HFILE_ERROR
;
102 end
= lseek(hFile
, 0, SEEK_END
);
103 if(end
== -1) return HFILE_ERROR
;
105 lseek(hFile
, prev
-1, SEEK_SET
);
106 result
= write(hFile
, &toWrite
, 1) - 1;
107 if(result
== -2) ++result
;
110 lseek(hFile
, prev
, SEEK_SET
);
114 else result
= write (hFile
, lpBuffer
, wBytes
);
122 /***************************************************************************
124 ***************************************************************************/
125 INT
_lclose (INT hFile
)
127 dprintf_file(stddeb
, "_lclose: handle %d\n", hFile
);
129 if (hFile
== 0 || hFile
== 1 || hFile
== 2) {
130 fprintf( stderr
, "Program attempted to close stdin, stdout or stderr!\n" );
139 /**************************************************************************
141 **************************************************************************/
142 INT
OpenFile (LPCSTR lpFileName
, LPOFSTRUCT ofs
, UINT wStyle
)
144 char filename
[MAX_PATH
+1];
151 dprintf_file(stddeb
,"Openfile(%s,<struct>,%d)\n",lpFileName
,wStyle
);
153 action
= wStyle
& 0xff00;
155 /* OF_CREATE is completly different from all other options, so
158 if (action
& OF_CREATE
)
162 if (!(action
& OF_REOPEN
)) strcpy(ofs
->szPathName
, lpFileName
);
163 ofs
->cBytes
= sizeof(OFSTRUCT
);
164 ofs
->fFixedDisk
= FALSE
;
166 *((int*)ofs
->reserved
) = 0;
168 if ((unixfilename
= DOS_GetUnixFileName (ofs
->szPathName
)) == NULL
)
171 ofs
->nErrCode
= ExtendedError
;
174 handle
= open (unixfilename
, (wStyle
& 0x0003) | O_CREAT
, 0666);
178 ofs
->nErrCode
= ExtendedError
;
184 /* If path isn't given, try to find the file. */
186 if (!(action
& OF_REOPEN
))
188 char temp
[MAX_PATH
+ 1];
190 if(index(lpFileName
,'\\') || index(lpFileName
,'/') ||
191 index(lpFileName
,':'))
193 strcpy (filename
,lpFileName
);
196 /* Try current directory */
197 if (DOS_FindFile(temp
, MAX_PATH
, lpFileName
, NULL
, ".")) {
198 strcpy(filename
, DOS_GetDosFileName(temp
));
202 /* Try Windows directory */
203 GetWindowsDirectory(filename
, MAX_PATH
);
204 if (DOS_FindFile(temp
, MAX_PATH
, lpFileName
, NULL
, filename
)) {
205 strcpy(filename
, DOS_GetDosFileName(temp
));
209 /* Try Windows system directory */
210 GetSystemDirectory(filename
, MAX_PATH
);
211 if (DOS_FindFile(temp
, MAX_PATH
, lpFileName
, NULL
, filename
)) {
212 strcpy(filename
, DOS_GetDosFileName(temp
));
216 /* Try the path of the current executable */
217 if (GetCurrentTask())
220 GetModuleFileName( GetCurrentTask(), filename
, MAX_PATH
);
221 if ((p
= strrchr( filename
, '\\' )))
224 if (DOS_FindFile(temp
, MAX_PATH
, lpFileName
, NULL
, filename
)) {
225 strcpy(filename
, DOS_GetDosFileName(temp
));
231 /* Try all directories in path */
233 if (DOS_FindFile(temp
,MAX_PATH
,lpFileName
,NULL
,WindowsPath
))
235 strcpy(filename
, DOS_GetDosFileName(temp
));
238 /* ??? shouldn't we give an error here? */
239 strcpy (filename
, lpFileName
);
243 ofs
->cBytes
= sizeof(OFSTRUCT
);
244 ofs
->fFixedDisk
= FALSE
;
245 strcpy(ofs
->szPathName
, filename
);
247 if (!(action
& OF_VERIFY
))
248 *((int*)ofs
->reserved
) = 0;
252 if (action
& OF_PARSE
)
255 if (action
& OF_DELETE
)
256 return unlink(ofs
->szPathName
);
259 /* Now on to getting some information about that file */
261 if ((res
= stat(DOS_GetUnixFileName(ofs
->szPathName
), &s
)))
264 ofs
->nErrCode
= ExtendedError
;
268 now
= localtime (&s
.st_mtime
);
270 if (action
& OF_VERIFY
)
271 verify_time
= *((int*)ofs
->reserved
);
273 *((WORD
*)(&ofs
->reserved
[2]))=
274 ((now
->tm_hour
* 0x2000) + (now
->tm_min
* 0x20) + (now
->tm_sec
/ 2));
275 *((WORD
*)(&ofs
->reserved
[0]))=
276 ((now
->tm_year
* 0x200) + (now
->tm_mon
* 0x20) + now
->tm_mday
);
278 if (action
& OF_VERIFY
)
279 return (verify_time
!= *((int*)ofs
->reserved
));
281 if ((handle
= _lopen( ofs
->szPathName
, wStyle
)) == -1)
283 ofs
->nErrCode
= 2; /* not found */
286 if (action
& OF_EXIST
) close(handle
);
291 /**************************************************************************
294 Changes the number of file handles available to the application. Since
295 Linux isn't limited to 20 files, this one's easy. - SL
296 **************************************************************************/
298 #if !defined (OPEN_MAX)
299 /* This one is for the Sun */
300 #define OPEN_MAX _POSIX_OPEN_MAX
302 WORD
SetHandleCount (WORD wNumber
)
304 dprintf_file(stddeb
,"SetHandleCount(%d)\n",wNumber
);
305 return((wNumber
<OPEN_MAX
) ? wNumber
: OPEN_MAX
);
308 /***************************************************************************
310 ***************************************************************************/
311 LONG
_llseek (INT hFile
, LONG lOffset
, INT nOrigin
)
315 dprintf_file(stddeb
, "_llseek: handle %d, offset %ld, origin %d\n",
316 hFile
, lOffset
, nOrigin
);
319 case 1: origin
= SEEK_CUR
;
321 case 2: origin
= SEEK_END
;
323 default: origin
= SEEK_SET
;
327 return lseek(hFile
, lOffset
, origin
);
330 /***************************************************************************
332 ***************************************************************************/
333 INT
_lcreat (LPSTR lpszFilename
, INT fnAttribute
)
338 dprintf_file(stddeb
, "_lcreat: filename %s, attributes %d\n",
339 lpszFilename
, fnAttribute
);
340 if ((UnixFileName
= DOS_GetUnixFileName(lpszFilename
)) == NULL
)
342 handle
= open (UnixFileName
, O_CREAT
| O_TRUNC
| O_RDWR
, 0666);
350 /***************************************************************************
352 ***************************************************************************/
353 UINT
GetDriveType(INT drive
)
356 dprintf_file(stddeb
,"GetDriveType %c:\n",'A'+drive
);
358 /* File Damager thinks that only return code 0 is bad enough
362 if (!DOS_ValidDrive(drive
))
363 return DRIVE_CANNOTDETERMINE
;
365 if (drive
== 0 || drive
== 1)
366 return DRIVE_REMOVABLE
;
371 /***************************************************************************
373 ***************************************************************************/
374 BYTE
GetTempDrive(BYTE chDriveLetter
)
376 dprintf_file(stddeb
,"GetTempDrive (%d)\n",chDriveLetter
);
377 if (TempDirectory
[1] == ':') return TempDirectory
[0];
381 /***************************************************************************
383 ***************************************************************************/
384 UINT
GetWindowsDirectory(LPSTR lpszSysPath
, UINT cbSysPath
)
386 if (cbSysPath
< strlen(WindowsDirectory
))
389 strcpy(lpszSysPath
, WindowsDirectory
);
391 dprintf_file(stddeb
,"GetWindowsDirectory (%s)\n",lpszSysPath
);
393 return strlen(lpszSysPath
);
395 /***************************************************************************
397 ***************************************************************************/
398 UINT
GetSystemDirectory(LPSTR lpszSysPath
, UINT cbSysPath
)
400 if (cbSysPath
< strlen(SystemDirectory
))
403 strcpy(lpszSysPath
, SystemDirectory
);
405 dprintf_file(stddeb
,"GetSystemDirectory (%s)\n",lpszSysPath
);
407 return strlen(lpszSysPath
);
409 /***************************************************************************
411 ***************************************************************************/
412 INT
GetTempFileName(BYTE bDriveLetter
, LPCSTR lpszPrefixString
, UINT uUnique
, LPSTR lpszTempFileName
)
419 unique
= time(NULL
)%99999L;
421 unique
= uUnique
%99999L;
423 strcpy(tempname
,lpszPrefixString
);
426 sprintf(lpszTempFileName
,"%s\\%s%d.tmp", TempDirectory
, tempname
,
429 ToDos(lpszTempFileName
);
431 dprintf_file(stddeb
,"GetTempFilename: %c %s %d => %s\n",bDriveLetter
,
432 lpszPrefixString
,uUnique
,lpszTempFileName
);
433 if ((handle
= _lcreat (lpszTempFileName
, 0x0000)) == -1) {
434 fprintf(stderr
,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName
);
442 /***************************************************************************
444 ***************************************************************************/
445 WORD
SetErrorMode(WORD x
)
447 dprintf_file(stdnimp
,"wine: SetErrorMode %4x (ignored)\n",x
);
452 /***************************************************************************
454 ***************************************************************************/
455 LONG
_hread(INT hf
, LPSTR hpvBuffer
, LONG cbBuffer
)
457 return (cbBuffer
== 0) ? 0 : read(hf
, hpvBuffer
, cbBuffer
);
459 /***************************************************************************
461 ***************************************************************************/
462 LONG
_hwrite(INT hf
, LPCSTR hpvBuffer
, LONG cbBuffer
)
464 return (cbBuffer
== 0) ? 0 : write(hf
, hpvBuffer
, cbBuffer
);