Release 941017
[wine/gsoc-2012-control.git] / misc / file.c
blob5a9d86a274a58520f4985cc37428e9568b1f84e5
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 <sys/stat.h>
26 #include <string.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"
34 #include "stddebug.h"
35 /* #define DEBUG_FILE /* */
36 /* #undef DEBUG_FILE /* */
37 #include "debug.h"
39 #define MAX_PATH 255
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 /***************************************************************************
51 _lopen
53 Emulate the _lopen windows call
54 ***************************************************************************/
55 INT _lopen (LPSTR lpPathName, INT iReadWrite)
57 int handle;
58 char *UnixFileName;
60 dprintf_file(stddeb, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite);
61 if ((UnixFileName = GetUnixFileName(lpPathName)) == NULL)
62 return HFILE_ERROR;
63 iReadWrite &= 0x000F;
64 handle = open (UnixFileName, iReadWrite);
66 dprintf_file(stddeb, "_lopen: open: %s (handle %d)\n", UnixFileName, handle);
68 if (handle == -1)
69 return HFILE_ERROR;
70 else
71 return handle;
74 /***************************************************************************
75 _lread
76 ***************************************************************************/
77 INT _lread (INT hFile, LPSTR lpBuffer, WORD wBytes)
79 int result;
81 dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
82 hFile, (int) lpBuffer, wBytes);
84 result = read (hFile, lpBuffer, wBytes);
86 if (result == -1)
87 return HFILE_ERROR;
88 else
89 return result;
92 /****************************************************************************
93 _lwrite
94 ****************************************************************************/
95 INT _lwrite (INT hFile, LPSTR lpBuffer, WORD wBytes)
97 int result;
99 dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
100 hFile, (int) lpBuffer, wBytes);
102 result = write (hFile, lpBuffer, wBytes);
104 if (result == -1)
105 return HFILE_ERROR;
106 else
107 return result;
110 /***************************************************************************
111 _lclose
112 ***************************************************************************/
113 INT _lclose (INT hFile)
115 dprintf_file(stddeb, "_lclose: handle %d\n", hFile);
116 if (close (hFile))
117 return HFILE_ERROR;
118 else
119 return 0;
122 /**************************************************************************
123 OpenFile
124 **************************************************************************/
125 INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
127 int handle;
128 #ifndef PROCEMU
129 struct sigcontext_struct ccontext;
130 /* To make macros like EAX happy */
131 struct sigcontext_struct *context=&ccontext;
132 #endif
133 char filename[MAX_PATH+1];
134 int action;
135 struct stat s;
136 struct tm *now;
137 int res;
138 int verify_time;
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
146 handle it first */
148 if (action & OF_CREATE)
150 int handle;
151 char *unixfilename;
153 if (!(action & OF_REOPEN))
154 strcpy(ofs->szPathName, lpFileName);
155 ofs->cBytes = sizeof(OFSTRUCT);
156 ofs->fFixedDisk = FALSE;
157 ofs->nErrCode = 0;
158 *((int*)ofs->reserved) = 0;
160 if ((unixfilename = GetUnixFileName (ofs->szPathName)) == NULL)
162 errno_to_doserr();
163 ofs->nErrCode = ExtendedError;
164 return -1;
166 handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
167 if (handle == -1)
169 errno_to_doserr();
170 ofs->nErrCode = ExtendedError;
172 return handle;
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,':')))
182 while(1)
184 char temp[MAX_PATH+1];
185 strcpy (filename, lpFileName);
186 if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
187 break;
188 GetWindowsDirectory (filename,MAX_PATH);
189 if (filename[1] != ':') strcat(filename,"\\");
190 strcat (filename, lpFileName);
191 if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
192 break;
193 GetSystemDirectory (filename,MAX_PATH);
194 if (filename[1] != ':') strcat(filename,"\\");
195 strcat (filename, lpFileName);
196 if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
197 break;
198 if (!FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
200 strcpy(filename, GetDosFileName(temp));
201 break;
203 strcpy (filename, lpFileName);
204 break;
206 else
207 strcpy (filename,lpFileName);
209 ofs->cBytes = sizeof(OFSTRUCT);
210 ofs->fFixedDisk = FALSE;
211 strcpy(ofs->szPathName, filename);
212 ofs->nErrCode = 0;
213 if (!(action & OF_VERIFY))
214 *((int*)ofs->reserved) = 0;
218 if (action & OF_PARSE)
219 return 0;
221 if (action & OF_DELETE)
222 return unlink(ofs->szPathName);
225 /* Now on to getting some information about that file */
227 if (res = stat(GetUnixFileName(ofs->szPathName), &s))
229 errno_to_doserr();
230 ofs->nErrCode = ExtendedError;
231 return -1;
234 now = localtime (&s.st_mtime);
236 if (action & OF_VERIFY)
237 verify_time = *((int*)ofs->reserved);
239 *((WORD*)(&ofs->reserved[2]))=
240 ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + (now->tm_sec / 2));
241 *((WORD*)(&ofs->reserved[0]))=
242 ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
244 if (action & OF_EXIST)
245 return 0;
247 if (action & OF_VERIFY)
248 return (verify_time != *((int*)ofs->reserved));
251 /* Now we are actually going to open the file. According to Microsoft's
252 Knowledge Basis, this is done by calling int 21h, ax=3dh. */
254 AX = 0x3d00;
255 AL = (AL & 0x0f) | (wStyle & 0x70); /* Handle OF_SHARE_xxx etc. */
256 AL = (AL & 0xf0) | (wStyle & 0x03); /* Handle OF_READ etc. */
257 DS = segment (ofs->szPathName);
258 DX = offset (ofs->szPathName);
260 OpenExistingFile (context);
262 if (EFL & 0x00000001) /* Cflag */
264 ofs->nErrCode = AL;
265 return -1;
268 return AX;
271 /**************************************************************************
272 SetHandleCount
274 Changes the number of file handles available to the application. Since
275 Linux isn't limited to 20 files, this one's easy. - SL
276 **************************************************************************/
278 #if !defined (OPEN_MAX)
279 /* This one is for the Sun */
280 #define OPEN_MAX _POSIX_OPEN_MAX
281 #endif
282 WORD SetHandleCount (WORD wNumber)
284 dprintf_file(stddeb,"SetHandleCount(%d)\n",wNumber);
285 return((wNumber<OPEN_MAX) ? wNumber : OPEN_MAX);
288 /***************************************************************************
289 _llseek
290 ***************************************************************************/
291 LONG _llseek (INT hFile, LONG lOffset, INT nOrigin)
293 int origin;
295 dprintf_file(stddeb, "_llseek: handle %d, offset %ld, origin %d\n",
296 hFile, lOffset, nOrigin);
298 switch (nOrigin) {
299 case 1: origin = SEEK_CUR;
300 break;
301 case 2: origin = SEEK_END;
302 break;
303 default: origin = SEEK_SET;
304 break;
307 return ( lseek(hFile, lOffset, origin) );
310 /***************************************************************************
311 _lcreat
312 ***************************************************************************/
313 INT _lcreat (LPSTR lpszFilename, INT fnAttribute)
315 int handle;
316 char *UnixFileName;
318 dprintf_file(stddeb, "_lcreat: filename %s, attributes %d\n",
319 lpszFilename, fnAttribute);
320 if ((UnixFileName = GetUnixFileName(lpszFilename)) == NULL)
321 return HFILE_ERROR;
322 handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 426);
324 if (handle == -1)
325 return HFILE_ERROR;
326 else
327 return handle;
330 /***************************************************************************
331 GetDriveType
332 ***************************************************************************/
333 UINT GetDriveType(INT drive)
336 dprintf_file(stddeb,"GetDriveType %c:\n",'A'+drive);
338 if (!DOS_ValidDrive(drive))
339 return DRIVE_DOESNOTEXIST;
341 if (drive == 0 || drive == 1)
342 return DRIVE_REMOVABLE;
344 return DRIVE_FIXED;
347 /***************************************************************************
348 GetTempDrive
349 ***************************************************************************/
350 BYTE GetTempDrive(BYTE chDriveLetter)
352 dprintf_file(stddeb,"GetTempDrive (%d)\n",chDriveLetter);
353 return('C');
356 /***************************************************************************
357 GetWindowsDirectory
358 ***************************************************************************/
359 UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath)
361 if (cbSysPath < strlen(WindowsDirectory))
362 *lpszSysPath = 0;
363 else
364 strcpy(lpszSysPath, WindowsDirectory);
366 dprintf_file(stddeb,"GetWindowsDirectory (%s)\n",lpszSysPath);
368 ChopOffSlash(lpszSysPath);
369 return(strlen(lpszSysPath));
371 /***************************************************************************
372 GetSystemDirectory
373 ***************************************************************************/
374 UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath)
376 if (cbSysPath < strlen(SystemDirectory))
377 *lpszSysPath = 0;
378 else
379 strcpy(lpszSysPath, SystemDirectory);
381 dprintf_file(stddeb,"GetSystemDirectory (%s)\n",lpszSysPath);
383 ChopOffSlash(lpszSysPath);
384 return(strlen(lpszSysPath));
386 /***************************************************************************
387 GetTempFileName
388 ***************************************************************************/
389 INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
391 int unique;
392 int handle;
393 char tempname[256];
395 if (uUnique == 0)
396 unique = time(NULL)%99999L;
397 else
398 unique = uUnique%99999L;
400 strcpy(tempname,lpszPrefixString);
401 tempname[3]='\0';
403 sprintf(lpszTempFileName,"%s\\%s%d.tmp", TempDirectory, tempname,
404 unique);
406 ToDos(lpszTempFileName);
408 dprintf_file(stddeb,"GetTempFilename: %c %s %d => %s\n",bDriveLetter,
409 lpszPrefixString,uUnique,lpszTempFileName);
410 if ((handle = _lcreat (lpszTempFileName, 0x0000)) == -1) {
411 fprintf(stderr,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName);
413 else
414 close(handle);
416 return unique;
419 /***************************************************************************
420 SetErrorMode
421 ***************************************************************************/
422 WORD SetErrorMode(WORD x)
424 dprintf_file(stdnimp,"wine: SetErrorMode %4x (ignored)\n",x);
427 /***************************************************************************
428 _hread
429 ***************************************************************************/
430 long _hread(int hf, void FAR *hpvBuffer, long cbBuffer)
432 return read(hf, hpvBuffer, cbBuffer);
434 /***************************************************************************
435 _hwrite
436 ***************************************************************************/
437 long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer)
439 return write(hf, hpvBuffer, cbBuffer);