Release 970509
[wine] / win32 / file.c
1 /*
2  * Win32 kernel functions
3  *
4  * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide
5  */
6
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <sys/mman.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <time.h>
17 #include "windows.h"
18 #include "winbase.h"
19 #include "winerror.h"
20 #include "file.h"
21 #include "heap.h"
22 #include "handle32.h"
23 #include "xmalloc.h"
24 #include "stddebug.h"
25 #define DEBUG_WIN32
26 #include "debug.h"
27
28
29 static int TranslateCreationFlags(DWORD create_flags);
30 static int TranslateAccessFlags(DWORD access_flags);
31
32 /***********************************************************************
33  *             WriteFile               (KERNEL32.578)
34  */
35 BOOL32 WriteFile(HFILE32 hFile, LPVOID lpBuffer, DWORD numberOfBytesToWrite,
36                  LPDWORD numberOfBytesWritten, LPOVERLAPPED lpOverlapped)
37 {
38     LONG        res;
39
40     res = _lwrite32(hFile,lpBuffer,numberOfBytesToWrite);
41     if (res==-1) {
42         SetLastError(ErrnoToLastError(errno));
43         return FALSE;
44     }
45     if(numberOfBytesWritten)
46         *numberOfBytesWritten = res;
47     return TRUE;
48 }
49
50 /***********************************************************************
51  *              ReadFile                (KERNEL32.428)
52  */
53 BOOL32 ReadFile(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread,
54                 LPDWORD numread, LPOVERLAPPED lpOverlapped)
55 {
56     int actual_read;
57
58     actual_read = _lread32(hFile,lpBuffer,numtoread);
59     if(actual_read == -1) {
60         SetLastError(ErrnoToLastError(errno));
61         return FALSE;
62     }
63     if(numread)
64         *numread = actual_read;
65
66     return TRUE;
67 }
68
69
70 /*************************************************************************
71  *              CreateFile32A              (KERNEL32.45)
72  *
73  * Doesn't support character devices, pipes, template files, or a
74  * lot of the 'attributes' flags yet.
75  */
76 HFILE32 CreateFile32A(LPCSTR filename, DWORD access, DWORD sharing,
77                       LPSECURITY_ATTRIBUTES security, DWORD creation,
78                       DWORD attributes, HANDLE32 template)
79 {
80     int access_flags, create_flags;
81
82     /* Translate the various flags to Unix-style.
83      */
84     access_flags = TranslateAccessFlags(access);
85     create_flags = TranslateCreationFlags(creation);
86
87     if(template)
88         dprintf_file(stddeb, "CreateFile: template handles not supported.\n");
89
90     /* If the name starts with '\\?' or '\\.', ignore the first 3 chars.
91      */
92     if(!strncmp(filename, "\\\\?", 3) || !strncmp(filename, "\\\\.", 3))
93         filename += 3;
94
95     /* If the name still starts with '\\', it's a UNC name.
96      */
97     if(!strncmp(filename, "\\\\", 2))
98     {
99         dprintf_file(stddeb, "CreateFile: UNC names not supported.\n");
100         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
101         return HFILE_ERROR32;
102     }
103
104     /* If the name is either CONIN$ or CONOUT$, give them stdin
105      * or stdout, respectively.
106      */
107     if(!strcmp(filename, "CONIN$")) return GetStdHandle( STD_INPUT_HANDLE );
108     if(!strcmp(filename, "CONOUT$")) return GetStdHandle( STD_OUTPUT_HANDLE );
109
110     return FILE_Open( filename, access_flags | create_flags );
111 }
112
113
114 /*************************************************************************
115  *              CreateFile32W              (KERNEL32.48)
116  */
117 HFILE32 CreateFile32W(LPCWSTR filename, DWORD access, DWORD sharing,
118                       LPSECURITY_ATTRIBUTES security, DWORD creation,
119                       DWORD attributes, HANDLE32 template)
120 {
121     LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
122     HFILE32 res = CreateFile32A( afn, access, sharing, security, creation,
123                                  attributes, template );
124     HeapFree( GetProcessHeap(), 0, afn );
125     return res;
126 }
127
128 static int TranslateAccessFlags(DWORD access_flags)
129 {
130     int rc = 0;
131
132     switch(access_flags)
133     {
134         case GENERIC_READ:
135             rc = O_RDONLY;
136             break;
137
138         case GENERIC_WRITE:
139             rc = O_WRONLY;
140             break;
141
142         case (GENERIC_READ | GENERIC_WRITE):
143             rc = O_RDWR;
144             break;
145     }
146
147     return rc;
148 }
149
150 static int TranslateCreationFlags(DWORD create_flags)
151 {
152     int rc = 0;
153
154     switch(create_flags)
155     {
156         case CREATE_NEW:
157             rc = O_CREAT | O_EXCL;
158             break;
159
160         case CREATE_ALWAYS:
161             rc = O_CREAT | O_TRUNC;
162             break;
163
164         case OPEN_EXISTING:
165             rc = 0;
166             break;
167
168         case OPEN_ALWAYS:
169             rc = O_CREAT;
170             break;
171
172         case TRUNCATE_EXISTING:
173             rc = O_TRUNC;
174             break;
175     }
176
177     return rc;
178 }
179
180
181 /**************************************************************************
182  *              SetFileAttributes16     (KERNEL.421)
183  */
184 BOOL16 SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
185 {
186     return SetFileAttributes32A( lpFileName, attributes );
187 }
188
189
190 /**************************************************************************
191  *              SetFileAttributes32A    (KERNEL32.490)
192  */
193 BOOL32 SetFileAttributes32A(LPCSTR lpFileName, DWORD attributes)
194 {
195     struct stat buf;
196     DOS_FULL_NAME full_name;
197
198     if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name ))
199         return FALSE;
200
201     dprintf_file(stddeb,"SetFileAttributes(%s,%lx)\n",lpFileName,attributes);
202     if(stat(full_name.long_name,&buf)==-1)
203     {
204         SetLastError(ErrnoToLastError(errno));
205         return FALSE;
206     }
207     if (attributes & FILE_ATTRIBUTE_READONLY)
208     {
209         buf.st_mode &= ~0222; /* octal!, clear write permission bits */
210         attributes &= ~FILE_ATTRIBUTE_READONLY;
211     }
212     attributes &= ~(FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
213     if (attributes)
214         fprintf(stdnimp,"SetFileAttributesA(%s):%lx attribute(s) not implemented.\n",lpFileName,attributes);
215     if (-1==chmod(full_name.long_name,buf.st_mode))
216     {
217         SetLastError(ErrnoToLastError(errno));
218         return FALSE;
219     }
220     return TRUE;
221 }
222
223 /**************************************************************************
224  *              SetFileAttributes32W    (KERNEL32.491)
225  */
226 BOOL32 SetFileAttributes32W(LPCWSTR lpFileName, DWORD attributes)
227 {
228     LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
229     BOOL32 res = SetFileAttributes32A( afn, attributes );
230     HeapFree( GetProcessHeap(), 0, afn );
231     return res;
232 }
233
234 VOID SetFileApisToOEM()
235 {
236     fprintf(stdnimp,"SetFileApisToOEM(),stub!\n");
237 }
238
239 VOID SetFileApisToANSI()
240 {
241     fprintf(stdnimp,"SetFileApisToANSI(),stub!\n");
242 }
243
244 BOOL32 AreFileApisANSI()
245 {
246     fprintf(stdnimp,"AreFileApisANSI(),stub!\n");
247     return TRUE;
248 }
249
250
251 BOOL32
252 LockFile(
253         HFILE32 hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,
254         DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh )
255 {
256         fprintf(stdnimp,"LockFile(%d,0x%08lx%08lx,0x%08lx%08lx),stub!\n",
257                 hFile,dwFileOffsetHigh,dwFileOffsetLow,
258                 nNumberOfBytesToLockHigh,nNumberOfBytesToLockLow
259         );
260         return TRUE;
261 }
262
263 BOOL32
264 UnlockFile(
265         HFILE32 hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,
266         DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh )
267 {
268         fprintf(stdnimp,"UnlockFile(%d,0x%08lx%08lx,0x%08lx%08lx),stub!\n",
269                 hFile,dwFileOffsetHigh,dwFileOffsetLow,
270                 nNumberOfBytesToUnlockHigh,nNumberOfBytesToUnlockLow
271         );
272         return TRUE;
273 }