Release 950727
[wine/multimedia.git] / misc / file.c
blob3581ce3d1f11ba53cfe83f48de33b8e0f81a7872
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 ************************************************************************/
18 #include <stdio.h>
19 #include <fcntl.h>
20 #include <limits.h>
21 #include <unistd.h>
22 #include <time.h>
23 #include <sys/stat.h>
24 #include <string.h>
25 #include "dos_fs.h"
26 #include "windows.h"
27 #include "msdos.h"
28 #include "options.h"
29 #include "stddebug.h"
30 #include "debug.h"
32 #define MAX_PATH 255
34 char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256];
36 /***************************************************************************
37 _lopen
39 Emulate the _lopen windows call
40 ***************************************************************************/
41 INT _lopen (LPSTR lpPathName, INT iReadWrite)
43 int handle;
44 char *UnixFileName;
45 int mode = 0;
47 dprintf_file(stddeb, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite);
48 if ((UnixFileName = DOS_GetUnixFileName(lpPathName)) == NULL)
49 return HFILE_ERROR;
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);
62 if (handle == -1)
63 return HFILE_ERROR;
64 else
65 return handle;
68 /***************************************************************************
69 _lread
70 ***************************************************************************/
71 INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
73 int result;
75 dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
76 hFile, (long) lpBuffer, wBytes);
78 result = wBytes == 0 ? 0 : read (hFile, lpBuffer, wBytes);
80 if (result == -1)
81 return HFILE_ERROR;
82 else
83 return result;
86 /****************************************************************************
87 _lwrite
88 ****************************************************************************/
89 INT _lwrite (INT hFile, LPCSTR lpBuffer, WORD wBytes)
91 int result;
93 dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
94 hFile, (long) lpBuffer, wBytes);
96 result = wBytes == 0 ? 0 : write (hFile, lpBuffer, wBytes);
98 if (result == -1)
99 return HFILE_ERROR;
100 else
101 return result;
104 /***************************************************************************
105 _lclose
106 ***************************************************************************/
107 INT _lclose (INT hFile)
109 dprintf_file(stddeb, "_lclose: handle %d\n", hFile);
111 if (hFile == 0 || hFile == 1 || hFile == 2) {
112 fprintf( stderr, "Program attempted to close stdin, stdout or stderr!\n" );
113 return 0;
115 if (close (hFile))
116 return HFILE_ERROR;
117 else
118 return 0;
121 /**************************************************************************
122 OpenFile
123 **************************************************************************/
124 INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
126 char filename[MAX_PATH+1];
127 int action;
128 struct stat s;
129 struct tm *now;
130 int res, handle;
131 int verify_time = 0;
133 dprintf_file(stddeb,"Openfile(%s,<struct>,%d)\n",lpFileName,wStyle);
135 action = wStyle & 0xff00;
138 /* OF_CREATE is completly different from all other options, so
139 handle it first */
141 if (action & OF_CREATE)
143 char *unixfilename;
145 if (!(action & OF_REOPEN)) strcpy(ofs->szPathName, lpFileName);
146 ofs->cBytes = sizeof(OFSTRUCT);
147 ofs->fFixedDisk = FALSE;
148 ofs->nErrCode = 0;
149 *((int*)ofs->reserved) = 0;
151 if ((unixfilename = DOS_GetUnixFileName (ofs->szPathName)) == NULL)
153 errno_to_doserr();
154 ofs->nErrCode = ExtendedError;
155 return -1;
157 handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0666);
158 if (handle == -1)
160 errno_to_doserr();
161 ofs->nErrCode = ExtendedError;
163 return handle;
167 /* If path isn't given, try to find the file. */
169 if (!(action & OF_REOPEN))
171 char temp[MAX_PATH + 1];
173 if(index(lpFileName,'\\') || index(lpFileName,'/') ||
174 index(lpFileName,':'))
176 strcpy (filename,lpFileName);
177 goto found;
179 /* Try current directory */
180 if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, ".")) {
181 strcpy(filename, DOS_GetDosFileName(temp));
182 goto found;
185 /* Try Windows directory */
186 GetWindowsDirectory(filename, MAX_PATH);
187 if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, filename)) {
188 strcpy(filename, DOS_GetDosFileName(temp));
189 goto found;
192 /* Try Windows system directory */
193 GetSystemDirectory(filename, MAX_PATH);
194 if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, filename)) {
195 strcpy(filename, DOS_GetDosFileName(temp));
196 goto found;
199 /* Try the path of the current executable */
200 if (GetCurrentTask())
202 char *p;
203 GetModuleFileName( GetCurrentTask(), filename, MAX_PATH );
204 if ((p = strrchr( filename, '\\' )))
206 p[1] = '\0';
207 if (DOS_FindFile(temp, MAX_PATH, lpFileName, NULL, filename)) {
208 strcpy(filename, DOS_GetDosFileName(temp));
209 goto found;
214 /* Try all directories in path */
216 if (DOS_FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
218 strcpy(filename, DOS_GetDosFileName(temp));
219 goto found;
221 /* ??? shouldn't we give an error here? */
222 strcpy (filename, lpFileName);
224 found:
226 ofs->cBytes = sizeof(OFSTRUCT);
227 ofs->fFixedDisk = FALSE;
228 strcpy(ofs->szPathName, filename);
229 ofs->nErrCode = 0;
230 if (!(action & OF_VERIFY))
231 *((int*)ofs->reserved) = 0;
235 if (action & OF_PARSE)
236 return 0;
238 if (action & OF_DELETE)
239 return unlink(ofs->szPathName);
242 /* Now on to getting some information about that file */
244 if ((res = stat(DOS_GetUnixFileName(ofs->szPathName), &s)))
246 errno_to_doserr();
247 ofs->nErrCode = ExtendedError;
248 return -1;
251 now = localtime (&s.st_mtime);
253 if (action & OF_VERIFY)
254 verify_time = *((int*)ofs->reserved);
256 *((WORD*)(&ofs->reserved[2]))=
257 ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + (now->tm_sec / 2));
258 *((WORD*)(&ofs->reserved[0]))=
259 ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
262 if (action & OF_VERIFY)
263 return (verify_time != *((int*)ofs->reserved));
265 if (action & OF_EXIST)
266 return 0;
268 if ((handle = _lopen( ofs->szPathName, wStyle )) == -1)
270 ofs->nErrCode = 2; /* not found */
271 return -1;
273 return handle;
277 /**************************************************************************
278 SetHandleCount
280 Changes the number of file handles available to the application. Since
281 Linux isn't limited to 20 files, this one's easy. - SL
282 **************************************************************************/
284 #if !defined (OPEN_MAX)
285 /* This one is for the Sun */
286 #define OPEN_MAX _POSIX_OPEN_MAX
287 #endif
288 WORD SetHandleCount (WORD wNumber)
290 dprintf_file(stddeb,"SetHandleCount(%d)\n",wNumber);
291 return((wNumber<OPEN_MAX) ? wNumber : OPEN_MAX);
294 /***************************************************************************
295 _llseek
296 ***************************************************************************/
297 LONG _llseek (INT hFile, LONG lOffset, INT nOrigin)
299 int origin;
301 dprintf_file(stddeb, "_llseek: handle %d, offset %ld, origin %d\n",
302 hFile, lOffset, nOrigin);
304 switch (nOrigin) {
305 case 1: origin = SEEK_CUR;
306 break;
307 case 2: origin = SEEK_END;
308 break;
309 default: origin = SEEK_SET;
310 break;
313 return lseek(hFile, lOffset, origin);
316 /***************************************************************************
317 _lcreat
318 ***************************************************************************/
319 INT _lcreat (LPSTR lpszFilename, INT fnAttribute)
321 int handle;
322 char *UnixFileName;
324 dprintf_file(stddeb, "_lcreat: filename %s, attributes %d\n",
325 lpszFilename, fnAttribute);
326 if ((UnixFileName = DOS_GetUnixFileName(lpszFilename)) == NULL)
327 return HFILE_ERROR;
328 handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 0666);
330 if (handle == -1)
331 return HFILE_ERROR;
332 else
333 return handle;
336 /***************************************************************************
337 GetDriveType
338 ***************************************************************************/
339 UINT GetDriveType(INT drive)
342 dprintf_file(stddeb,"GetDriveType %c:\n",'A'+drive);
344 if (!DOS_ValidDrive(drive))
345 return DRIVE_DOESNOTEXIST;
347 if (drive == 0 || drive == 1)
348 return DRIVE_REMOVABLE;
350 return DRIVE_FIXED;
353 /***************************************************************************
354 GetTempDrive
355 ***************************************************************************/
356 BYTE GetTempDrive(BYTE chDriveLetter)
358 dprintf_file(stddeb,"GetTempDrive (%d)\n",chDriveLetter);
359 if (TempDirectory[1] == ':') return TempDirectory[0];
360 else return 'C';
363 /***************************************************************************
364 GetWindowsDirectory
365 ***************************************************************************/
366 UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath)
368 if (cbSysPath < strlen(WindowsDirectory))
369 *lpszSysPath = 0;
370 else
371 strcpy(lpszSysPath, WindowsDirectory);
373 dprintf_file(stddeb,"GetWindowsDirectory (%s)\n",lpszSysPath);
375 return strlen(lpszSysPath);
377 /***************************************************************************
378 GetSystemDirectory
379 ***************************************************************************/
380 UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath)
382 if (cbSysPath < strlen(SystemDirectory))
383 *lpszSysPath = 0;
384 else
385 strcpy(lpszSysPath, SystemDirectory);
387 dprintf_file(stddeb,"GetSystemDirectory (%s)\n",lpszSysPath);
389 return strlen(lpszSysPath);
391 /***************************************************************************
392 GetTempFileName
393 ***************************************************************************/
394 INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
396 int unique;
397 int handle;
398 char tempname[256];
400 if (uUnique == 0)
401 unique = time(NULL)%99999L;
402 else
403 unique = uUnique%99999L;
405 strcpy(tempname,lpszPrefixString);
406 tempname[3]='\0';
408 sprintf(lpszTempFileName,"%s\\%s%d.tmp", TempDirectory, tempname,
409 unique);
411 ToDos(lpszTempFileName);
413 dprintf_file(stddeb,"GetTempFilename: %c %s %d => %s\n",bDriveLetter,
414 lpszPrefixString,uUnique,lpszTempFileName);
415 if ((handle = _lcreat (lpszTempFileName, 0x0000)) == -1) {
416 fprintf(stderr,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName);
418 else
419 close(handle);
421 return unique;
424 /***************************************************************************
425 SetErrorMode
426 ***************************************************************************/
427 WORD SetErrorMode(WORD x)
429 dprintf_file(stdnimp,"wine: SetErrorMode %4x (ignored)\n",x);
431 return 1;
434 /***************************************************************************
435 _hread
436 ***************************************************************************/
437 LONG _hread(INT hf, LPSTR hpvBuffer, LONG cbBuffer)
439 return cbBuffer == 0 ? 0 : read(hf, hpvBuffer, cbBuffer);
441 /***************************************************************************
442 _hwrite
443 ***************************************************************************/
444 LONG _hwrite(INT hf, LPCSTR hpvBuffer, LONG cbBuffer)
446 return cbBuffer == 0 ? 0 : write(hf, hpvBuffer, cbBuffer);