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);
55 dprintf_file(stddeb, "_lopen: open: %s (handle %d)\n", UnixFileName, handle);
63 /***************************************************************************
65 ***************************************************************************/
66 INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
70 dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
71 hFile, (long) lpBuffer, wBytes);
73 result = read (hFile, lpBuffer, wBytes);
81 /****************************************************************************
83 ****************************************************************************/
84 INT _lwrite (INT hFile, LPSTR lpBuffer, WORD wBytes)
88 dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
89 hFile, (long) lpBuffer, wBytes);
91 result = write (hFile, lpBuffer, wBytes);
99 /***************************************************************************
101 ***************************************************************************/
102 INT _lclose (INT hFile)
104 dprintf_file(stddeb, "_lclose: handle %d\n", hFile);
111 /**************************************************************************
113 **************************************************************************/
114 INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
117 dprintf_file(stdnimp, "OpenFile: not implemented\n");
120 struct sigcontext_struct ccontext;
121 /* To make macros like EAX happy */
122 struct sigcontext_struct *context=&ccontext;
124 char filename[MAX_PATH+1];
131 dprintf_file(stddeb,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
133 action = wStyle & 0xff00;
136 /* OF_CREATE is completly different from all other options, so
139 if (action & OF_CREATE)
144 if (!(action & OF_REOPEN))
145 strcpy(ofs->szPathName, lpFileName);
146 ofs->cBytes = sizeof(OFSTRUCT);
147 ofs->fFixedDisk = FALSE;
149 *((int*)ofs->reserved) = 0;
151 if ((unixfilename = DOS_GetUnixFileName (ofs->szPathName)) == NULL)
154 ofs->nErrCode = ExtendedError;
157 handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
161 ofs->nErrCode = ExtendedError;
167 /* If path isn't given, try to find the file. */
169 if (!(action & OF_REOPEN))
171 if( !( index(lpFileName,'\\') || index(lpFileName,'/') ||
172 index(lpFileName,':')))
175 char temp[MAX_PATH+1];
176 strcpy (filename, lpFileName);
177 if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
179 GetWindowsDirectory (filename,MAX_PATH);
180 if ((!filename[0])||(filename[strlen(filename)-1]!='\\'))
181 strcat(filename, "\\");
182 strcat (filename, lpFileName);
183 if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
185 GetSystemDirectory (filename,MAX_PATH);
186 if ((!filename[0])||(filename[strlen(filename)-1]!='\\'))
187 strcat(filename, "\\");
188 strcat (filename, lpFileName);
189 if ( (!stat(DOS_GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
191 if (!DOS_FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
193 strcpy(filename, DOS_GetDosFileName(temp));
196 strcpy (filename, lpFileName);
200 strcpy (filename,lpFileName);
202 ofs->cBytes = sizeof(OFSTRUCT);
203 ofs->fFixedDisk = FALSE;
204 strcpy(ofs->szPathName, filename);
206 if (!(action & OF_VERIFY))
207 *((int*)ofs->reserved) = 0;
211 if (action & OF_PARSE)
214 if (action & OF_DELETE)
215 return unlink(ofs->szPathName);
218 /* Now on to getting some information about that file */
220 if ((res = stat(DOS_GetUnixFileName(ofs->szPathName), &s)))
223 ofs->nErrCode = ExtendedError;
227 now = localtime (&s.st_mtime);
229 if (action & OF_VERIFY)
230 verify_time = *((int*)ofs->reserved);
232 *((WORD*)(&ofs->reserved[2]))=
233 ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + (now->tm_sec / 2));
234 *((WORD*)(&ofs->reserved[0]))=
235 ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
238 if (action & OF_VERIFY)
239 return (verify_time != *((int*)ofs->reserved));
241 if (action & OF_EXIST)
244 /* Now we are actually going to open the file. According to Microsoft's
245 Knowledge Basis, this is done by calling int 21h, ax=3dh. */
248 AL = (AL & 0x0f) | (wStyle & 0x70); /* Handle OF_SHARE_xxx etc. */
249 AL = (AL & 0xf0) | (wStyle & 0x03); /* Handle OF_READ etc. */
250 DS = segment (ofs->szPathName);
251 DX = offset (ofs->szPathName);
253 OpenExistingFile (context);
255 if (EFL & 0x00000001) /* Cflag */
265 /**************************************************************************
268 Changes the number of file handles available to the application. Since
269 Linux isn't limited to 20 files, this one's easy. - SL
270 **************************************************************************/
272 #if !defined (OPEN_MAX)
273 /* This one is for the Sun */
274 #define OPEN_MAX _POSIX_OPEN_MAX
276 WORD SetHandleCount (WORD wNumber)
278 dprintf_file(stddeb,"SetHandleCount(%d)\n",wNumber);
279 return((wNumber<OPEN_MAX) ? wNumber : OPEN_MAX);
282 /***************************************************************************
284 ***************************************************************************/
285 LONG _llseek (INT hFile, LONG lOffset, INT nOrigin)
289 dprintf_file(stddeb, "_llseek: handle %d, offset %ld, origin %d\n",
290 hFile, lOffset, nOrigin);
293 case 1: origin = SEEK_CUR;
295 case 2: origin = SEEK_END;
297 default: origin = SEEK_SET;
301 return ( lseek(hFile, lOffset, origin) );
304 /***************************************************************************
306 ***************************************************************************/
307 INT _lcreat (LPSTR lpszFilename, INT fnAttribute)
312 dprintf_file(stddeb, "_lcreat: filename %s, attributes %d\n",
313 lpszFilename, fnAttribute);
314 if ((UnixFileName = DOS_GetUnixFileName(lpszFilename)) == NULL)
316 handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 426);
324 /***************************************************************************
326 ***************************************************************************/
327 UINT GetDriveType(INT drive)
330 dprintf_file(stddeb,"GetDriveType %c:\n",'A'+drive);
332 if (!DOS_ValidDrive(drive))
333 return DRIVE_DOESNOTEXIST;
335 if (drive == 0 || drive == 1)
336 return DRIVE_REMOVABLE;
341 /***************************************************************************
343 ***************************************************************************/
344 BYTE GetTempDrive(BYTE chDriveLetter)
346 dprintf_file(stddeb,"GetTempDrive (%d)\n",chDriveLetter);
350 /***************************************************************************
352 ***************************************************************************/
353 UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath)
355 if (cbSysPath < strlen(WindowsDirectory))
358 strcpy(lpszSysPath, WindowsDirectory);
360 dprintf_file(stddeb,"GetWindowsDirectory (%s)\n",lpszSysPath);
362 ChopOffSlash(lpszSysPath);
363 return(strlen(lpszSysPath));
365 /***************************************************************************
367 ***************************************************************************/
368 UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath)
370 if (cbSysPath < strlen(SystemDirectory))
373 strcpy(lpszSysPath, SystemDirectory);
375 dprintf_file(stddeb,"GetSystemDirectory (%s)\n",lpszSysPath);
377 ChopOffSlash(lpszSysPath);
378 return(strlen(lpszSysPath));
380 /***************************************************************************
382 ***************************************************************************/
383 INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
390 unique = time(NULL)%99999L;
392 unique = uUnique%99999L;
394 strcpy(tempname,lpszPrefixString);
397 sprintf(lpszTempFileName,"%s\\%s%d.tmp", TempDirectory, tempname,
400 ToDos(lpszTempFileName);
402 dprintf_file(stddeb,"GetTempFilename: %c %s %d => %s\n",bDriveLetter,
403 lpszPrefixString,uUnique,lpszTempFileName);
404 if ((handle = _lcreat (lpszTempFileName, 0x0000)) == -1) {
405 fprintf(stderr,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName);
413 /***************************************************************************
415 ***************************************************************************/
416 WORD SetErrorMode(WORD x)
418 dprintf_file(stdnimp,"wine: SetErrorMode %4x (ignored)\n",x);
423 /***************************************************************************
425 ***************************************************************************/
426 long _hread(int hf, void FAR *hpvBuffer, long cbBuffer)
428 return read(hf, hpvBuffer, cbBuffer);
430 /***************************************************************************
432 ***************************************************************************/
433 long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer)
435 return write(hf, hpvBuffer, cbBuffer);