Release 940912
[wine/multimedia.git] / misc / file.c
blob0551a6a27d747272c62109867785fe38cb2102b2
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 ************************************************************************/
20 #include <stdio.h>
21 #include <fcntl.h>
22 #include <limits.h>
23 #include <unistd.h>
24 #include <time.h>
25 #include <windows.h>
26 #include <sys/stat.h>
27 #include "prototypes.h"
28 #include "regfunc.h"
29 #include "windows.h"
30 #include "wine.h"
31 #include "msdos.h"
32 #include "registers.h"
33 #include "options.h"
35 #define MAX_PATH 255
37 /* #define DEBUG_FILE /* */
39 char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256];
40 extern char WindowsPath[256];
42 extern char WindowsPath[];
43 extern WORD ExtendedError;
46 char *GetDosFileName(char *unixfilename);
48 /***************************************************************************
49 _lopen
51 Emulate the _lopen windows call
52 ***************************************************************************/
53 INT _lopen (LPSTR lpPathName, INT iReadWrite)
55 int handle;
56 char *UnixFileName;
58 #ifdef DEBUG_FILE
59 fprintf (stderr, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite);
60 #endif
62 if ((UnixFileName = GetUnixFileName(lpPathName)) == NULL)
63 return HFILE_ERROR;
64 iReadWrite &= 0x000F;
65 handle = open (UnixFileName, iReadWrite);
67 #ifdef DEBUG_FILE
68 fprintf (stderr, "_lopen: open: %s (handle %d)\n", UnixFileName, handle);
69 #endif
71 if (handle == -1)
72 return HFILE_ERROR;
73 else
74 return handle;
77 /***************************************************************************
78 _lread
79 ***************************************************************************/
80 INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
82 int result;
84 #ifdef DEBUG_FILE
85 fprintf(stderr, "_lread: handle %d, buffer = %ld, length = %d\n",
86 hFile, (int) lpBuffer, wBytes);
87 #endif
89 result = read (hFile, lpBuffer, wBytes);
91 if (result == -1)
92 return HFILE_ERROR;
93 else
94 return result;
97 /****************************************************************************
98 _lwrite
99 ****************************************************************************/
100 INT _lwrite (INT hFile, LPSTR lpBuffer, WORD wBytes)
102 int result;
104 #if 0
105 #ifdef DEBUG_FILE
106 fprintf(stderr, "_lwrite: handle %d, buffer = %ld, length = %d\n",
107 hFile, (int) lpBuffer, wBytes);
108 #endif
109 #endif
110 result = write (hFile, lpBuffer, wBytes);
112 if (result == -1)
113 return HFILE_ERROR;
114 else
115 return result;
118 /***************************************************************************
119 _lclose
120 ***************************************************************************/
121 INT _lclose (INT hFile)
123 #ifdef DEBUG_FILE
124 fprintf(stderr, "_lclose: handle %d\n", hFile);
125 #endif
126 if (close (hFile))
127 return HFILE_ERROR;
128 else
129 return 0;
132 /**************************************************************************
133 OpenFile
134 **************************************************************************/
135 INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
137 int handle;
138 struct sigcontext_struct ccontext;
139 /* To make macros like EAX happy */
140 struct sigcontext_struct *context=&ccontext;
141 char filename[MAX_PATH+1];
142 int action;
143 struct stat s;
144 struct tm *now;
145 int res;
146 int verify_time;
148 #ifdef DEBUG_FILE
149 fprintf(stderr,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
150 #endif
152 action = wStyle & 0xff00;
155 /* OF_CREATE is completly different from all other options, so
156 handle it first */
158 if (action & OF_CREATE)
160 int handle;
161 char *unixfilename;
163 if (!(action & OF_REOPEN))
164 strcpy(ofs->szPathName, lpFileName);
165 ofs->cBytes = sizeof(OFSTRUCT);
166 ofs->fFixedDisk = FALSE;
167 ofs->nErrCode = 0;
168 *((int*)ofs->reserved) = 0;
170 if ((unixfilename = GetUnixFileName (ofs->szPathName)) == NULL)
172 errno_to_doserr();
173 ofs->nErrCode = ExtendedError;
174 return -1;
176 handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
177 if (handle == -1)
179 errno_to_doserr();
180 ofs->nErrCode = ExtendedError;
182 return handle;
186 /* If path isn't given, try to find the file. */
188 if (!(action & OF_REOPEN))
190 if( !( index(lpFileName,'\\') || index(lpFileName,'/') ||
191 index(lpFileName,':')))
192 while(1)
194 char temp[MAX_PATH+1];
195 strcpy (filename, lpFileName);
196 if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
197 break;
198 GetWindowsDirectory (filename,MAX_PATH);
199 if (filename[1] != ':')
200 strcat(filename,'\\');
201 strcat (filename, lpFileName);
202 if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
203 break;
204 GetSystemDirectory (filename,MAX_PATH);
205 if (filename[1] != ':')
206 strcat(filename,'\\');
207 strcat (filename, lpFileName);
208 if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
209 break;
210 if (!FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
212 strcpy(filename, GetDosFileName(temp));
213 break;
215 strcpy (filename, lpFileName);
216 break;
218 else
219 strcpy (filename,lpFileName);
221 ofs->cBytes = sizeof(OFSTRUCT);
222 ofs->fFixedDisk = FALSE;
223 strcpy(ofs->szPathName, filename);
224 ofs->nErrCode = 0;
225 if (!(action & OF_VERIFY))
226 *((int*)ofs->reserved) = 0;
230 if (action & OF_PARSE)
231 return 0;
233 if (action & OF_DELETE)
234 return unlink(ofs->szPathName);
237 /* Now on to getting some information about that file */
239 if (res = stat(GetUnixFileName(ofs->szPathName), &s))
241 errno_to_doserr();
242 ofs->nErrCode = ExtendedError;
243 return -1;
246 now = localtime (&s.st_mtime);
248 if (action & OF_VERIFY)
249 verify_time = *((int*)ofs->reserved);
251 *((WORD*)(&ofs->reserved[2]))=
252 ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + (now->tm_sec / 2));
253 *((WORD*)(&ofs->reserved[0]))=
254 ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
256 if (action & OF_EXIST)
257 return 0;
259 if (action & OF_VERIFY)
260 return (verify_time != *((int*)ofs->reserved));
263 /* Now we are actually going to open the file. According to Microsoft's
264 Knowledge Basis, this is done by calling int 21h, ax=3dh. */
266 EAX = 0x00003d00;
267 EAX = (EAX & 0xffffff0f) | (wStyle & 0x0070); /* Handle OF_SHARE_xxx etc. */
268 EAX = (EAX & 0xfffffff0) | (wStyle & 0x0003); /* Handle OF_READ etc. */
269 DS = segment (ofs->szPathName);
270 EDX = (EDX & 0xffff0000) | offset (ofs->szPathName);
272 OpenExistingFile (context);
274 if (EFL & 0x00000001) /* Cflag */
276 ofs->nErrCode = (AX & 0x00ff);
277 return -1;
280 return AX;
283 /**************************************************************************
284 SetHandleCount
286 Changes the number of file handles available to the application. Since
287 Linux isn't limited to 20 files, this one's easy. - SL
288 **************************************************************************/
290 #if !defined (OPEN_MAX)
291 /* This one is for the Sun */
292 #define OPEN_MAX _POSIX_OPEN_MAX
293 #endif
294 WORD SetHandleCount (WORD wNumber)
296 printf("SetHandleCount(%d)\n",wNumber);
297 return((wNumber<OPEN_MAX) ? wNumber : OPEN_MAX);
300 /***************************************************************************
301 _llseek
302 ***************************************************************************/
303 LONG _llseek (INT hFile, LONG lOffset, INT nOrigin)
305 int origin;
307 #ifdef DEBUG_FILE
308 fprintf(stderr, "_llseek: handle %d, offset %ld, origin %d\n", hFile, lOffset, nOrigin);
309 #endif
311 switch (nOrigin) {
312 case 1: origin = SEEK_CUR;
313 break;
314 case 2: origin = SEEK_END;
315 break;
316 default: origin = SEEK_SET;
317 break;
320 return ( lseek(hFile, lOffset, origin) );
323 /***************************************************************************
324 _lcreat
325 ***************************************************************************/
326 INT _lcreat (LPSTR lpszFilename, INT fnAttribute)
328 int handle;
329 char *UnixFileName;
331 #ifdef DEBUG_FILE
332 fprintf(stderr, "_lcreat: filename %s, attributes %d\n",lpszFilename,
333 fnAttribute);
334 #endif
335 if ((UnixFileName = GetUnixFileName(lpszFilename)) == NULL)
336 return HFILE_ERROR;
337 handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 426);
339 if (handle == -1)
340 return HFILE_ERROR;
341 else
342 return handle;
345 /***************************************************************************
346 GetDriveType
347 ***************************************************************************/
348 UINT GetDriveType(INT drive)
351 #ifdef DEBUG_FILE
352 fprintf(stderr,"GetDriveType %c:\n",'A'+drive);
353 #endif
355 if (!DOS_ValidDrive(drive))
356 return DRIVE_DOESNOTEXIST;
358 if (drive == 0 || drive == 1)
359 return DRIVE_REMOVABLE;
361 return DRIVE_FIXED;
364 /***************************************************************************
365 GetTempDrive
366 ***************************************************************************/
367 BYTE GetTempDrive(BYTE chDriveLetter)
369 #ifdef DEBUG_FILE
370 fprintf(stderr,"GetTempDrive (%d)\n",chDriveLetter);
371 #endif
372 return('C');
375 /***************************************************************************
376 GetWindowsDirectory
377 ***************************************************************************/
378 UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath)
380 if (cbSysPath < strlen(WindowsDirectory))
381 *lpszSysPath = 0;
382 else
383 strcpy(lpszSysPath, WindowsDirectory);
385 #ifdef DEBUG_FILE
386 fprintf(stderr,"GetWindowsDirectory (%s)\n",lpszSysPath);
387 #endif
389 ChopOffSlash(lpszSysPath);
390 return(strlen(lpszSysPath));
392 /***************************************************************************
393 GetSystemDirectory
394 ***************************************************************************/
395 UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath)
397 if (cbSysPath < strlen(SystemDirectory))
398 *lpszSysPath = 0;
399 else
400 strcpy(lpszSysPath, SystemDirectory);
402 #ifdef DEBUG_FILE
403 fprintf(stderr,"GetSystemDirectory (%s)\n",lpszSysPath);
404 #endif
406 ChopOffSlash(lpszSysPath);
407 return(strlen(lpszSysPath));
409 /***************************************************************************
410 GetTempFileName
411 ***************************************************************************/
412 INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
414 int unique;
415 int handle;
416 char tempname[256];
418 if (uUnique == 0)
419 unique = time(NULL)%99999L;
420 else
421 unique = uUnique%99999L;
423 strcpy(tempname,lpszPrefixString);
424 tempname[3]='\0';
426 sprintf(lpszTempFileName,"%s\\%s%d.tmp", TempDirectory, tempname,
427 unique);
429 ToDos(lpszTempFileName);
431 #ifdef DEBUG_FILE
432 fprintf(stderr,"GetTempFilename: %c %s %d => %s\n",bDriveLetter,
433 lpszPrefixString,uUnique,lpszTempFileName);
434 #endif
435 if ((handle = _lcreat (lpszTempFileName, 0x0000)) == -1) {
436 fprintf(stderr,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName);
438 else
439 close(handle);
441 return unique;
444 /***************************************************************************
445 SetErrorMode
446 ***************************************************************************/
447 WORD SetErrorMode(WORD x)
449 fprintf(stderr,"wine: SetErrorMode %4x (ignored)\n",x);
452 /***************************************************************************
453 _hread
454 ***************************************************************************/
455 long _hread(int hf, void FAR *hpvBuffer, long cbBuffer)
457 return read(hf, hpvBuffer, cbBuffer);
459 /***************************************************************************
460 _hwrite
461 ***************************************************************************/
462 long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer)
464 return write(hf, hpvBuffer, cbBuffer);