New stubs PrivateExtractIconEx[AW], PrivateExtractIconsW,
[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 <sys/errno.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 "device.h"
22 #include "process.h"
23 #include "heap.h"
24 #include "debug.h"
25
26 DWORD ErrnoToLastError(int errno_num);
27
28 static int TranslateCreationFlags(DWORD create_flags);
29 static int TranslateAccessFlags(DWORD access_flags);
30
31 /***********************************************************************
32  *             WriteFile               (KERNEL32.578)
33  */
34 BOOL32 WINAPI WriteFile(HANDLE32 hFile, LPCVOID lpBuffer, 
35                         DWORD numberOfBytesToWrite,
36                         LPDWORD numberOfBytesWritten, LPOVERLAPPED lpOverlapped)
37 {
38         K32OBJ *ioptr;
39         BOOL32 status = FALSE;
40         
41         TRACE(file, "%d %p %ld\n", hFile, lpBuffer, 
42                      numberOfBytesToWrite);
43         
44         if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
45                                         K32OBJ_UNKNOWN, 0, NULL ))) 
46                 return HFILE_ERROR32;
47         if (K32OBJ_OPS(ioptr)->write)
48             status = K32OBJ_OPS(ioptr)->write(ioptr, lpBuffer, numberOfBytesToWrite, 
49                                               numberOfBytesWritten, lpOverlapped);
50         K32OBJ_DecCount( ioptr );
51         return status;
52 }
53
54 /***********************************************************************
55  *              ReadFile                (KERNEL32.428)
56  */
57 BOOL32 WINAPI ReadFile(HANDLE32 hFile, LPVOID lpBuffer, DWORD numberOfBytesToRead,
58                        LPDWORD numberOfBytesRead, LPOVERLAPPED lpOverlapped)
59 {
60         K32OBJ *ioptr;
61         BOOL32 status = FALSE;
62         
63         TRACE(file, "%d %p %ld\n", hFile, lpBuffer, 
64                      numberOfBytesToRead);
65         
66         if (!(ioptr = HANDLE_GetObjPtr( PROCESS_Current(), hFile,
67                                         K32OBJ_UNKNOWN, 0, NULL ))) 
68                 return HFILE_ERROR32;
69         if (K32OBJ_OPS(ioptr)->read)
70             status = K32OBJ_OPS(ioptr)->read(ioptr, lpBuffer, numberOfBytesToRead, 
71                                              numberOfBytesRead, lpOverlapped);
72         K32OBJ_DecCount( ioptr );
73         return status;
74 }
75
76
77 /***********************************************************************
78  *              ReadFileEx                (KERNEL32.)
79  */
80 typedef
81 VOID
82 (CALLBACK *LPOVERLAPPED_COMPLETION_ROUTINE)(
83     DWORD dwErrorCode,
84     DWORD dwNumberOfBytesTransfered,
85     LPOVERLAPPED lpOverlapped
86     );
87
88 BOOL32 WINAPI ReadFileEx(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread,
89                          LPOVERLAPPED lpOverlapped, 
90                          LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
91 {
92
93     FIXME(file, "file %d to buf %p num %ld %p func %p stub\n",
94           hFile, lpBuffer, numtoread, lpOverlapped, lpCompletionRoutine);
95     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
96     return 0;
97 }
98
99
100 /*************************************************************************
101  * CreateFile32A [KERNEL32.45]  Creates or opens a file or other object
102  *
103  * Creates or opens an object, and returns a handle that can be used to
104  * access that object.
105  *
106  * PARAMS
107  *
108  * filename     [I] pointer to filename to be accessed
109  * access       [I] access mode requested
110  * sharing      [I] share mode
111  * security     [I] pointer to security attributes
112  * creation     [I] ?
113  * attributes   [I] ?
114  * template     [I] handle to file with attributes to copy
115  *
116  * RETURNS
117  *   Success: Open handle to specified file
118  *   Failure: INVALID_HANDLE_VALUE
119  *
120  * NOTES
121  *  Should call SetLastError() on failure.
122  *
123  * BUGS
124  *
125  * Doesn't support character devices, pipes, template files, or a
126  * lot of the 'attributes' flags yet.
127  */
128 HFILE32 WINAPI CreateFile32A(LPCSTR filename, DWORD access, DWORD sharing,
129                              LPSECURITY_ATTRIBUTES security, DWORD creation,
130                              DWORD attributes, HANDLE32 template)
131 {
132     int access_flags, create_flags;
133     HFILE32 to_dup = HFILE_ERROR32; /* handle to dup */
134
135     /* Translate the various flags to Unix-style.
136      */
137     access_flags = TranslateAccessFlags(access);
138     create_flags = TranslateCreationFlags(creation);
139
140     if(template)
141         FIXME(file, "template handles not supported.\n");
142
143     if(!filename)
144       return HFILE_ERROR32;
145     /* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars.
146      */
147     if(!strncmp(filename, "\\\\?\\", 4) || !strncmp(filename, "\\\\.\\", 4))
148     {
149         if (filename[2] == '.')
150             return DEVICE_Open( filename+4, access_flags | create_flags );
151
152         filename += 4;
153         if (!strncmp(filename, "UNC", 3))
154         {
155             FIXME(file, "UNC names not supported.\n");
156             SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
157             return HFILE_ERROR32;
158         }       
159     }
160
161     /* If the name still starts with '\\', it's a UNC name.
162      */
163     if(!strncmp(filename, "\\\\", 2))
164     {
165         FIXME(file, "UNC names not supported.\n");
166         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
167         return HFILE_ERROR32;
168     }
169
170     /* If the name is either CONIN$ or CONOUT$, give them duplicated stdin
171      * or stdout, respectively.
172      */
173     if(!strcmp(filename, "CONIN$"))
174         to_dup = GetStdHandle( STD_INPUT_HANDLE );
175     else if(!strcmp(filename, "CONOUT$"))
176         to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
177
178     if(to_dup != HFILE_ERROR32)
179     {
180         HFILE32 handle;
181         if (!DuplicateHandle( GetCurrentProcess(), to_dup, GetCurrentProcess(),
182                               &handle, access, FALSE, 0 ))
183             handle = HFILE_ERROR32;
184         return handle;
185     }
186     return FILE_Open( filename, access_flags | create_flags );
187 }
188
189
190 /*************************************************************************
191  *              CreateFile32W              (KERNEL32.48)
192  */
193 HFILE32 WINAPI CreateFile32W(LPCWSTR filename, DWORD access, DWORD sharing,
194                              LPSECURITY_ATTRIBUTES security, DWORD creation,
195                              DWORD attributes, HANDLE32 template)
196 {
197     LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
198     HFILE32 res = CreateFile32A( afn, access, sharing, security, creation,
199                                  attributes, template );
200     HeapFree( GetProcessHeap(), 0, afn );
201     return res;
202 }
203
204 static int TranslateAccessFlags(DWORD access_flags)
205 {
206     int rc = 0;
207
208     switch(access_flags)
209     {
210         case GENERIC_READ:
211             rc = O_RDONLY;
212             break;
213
214         case GENERIC_WRITE:
215             rc = O_WRONLY;
216             break;
217
218         case (GENERIC_READ | GENERIC_WRITE):
219             rc = O_RDWR;
220             break;
221     }
222
223     return rc;
224 }
225
226 static int TranslateCreationFlags(DWORD create_flags)
227 {
228     int rc = 0;
229
230     switch(create_flags)
231     {
232         case CREATE_NEW:
233             rc = O_CREAT | O_EXCL;
234             break;
235
236         case CREATE_ALWAYS:
237             rc = O_CREAT | O_TRUNC;
238             break;
239
240         case OPEN_EXISTING:
241             rc = 0;
242             break;
243
244         case OPEN_ALWAYS:
245             rc = O_CREAT;
246             break;
247
248         case TRUNCATE_EXISTING:
249             rc = O_TRUNC;
250             break;
251     }
252
253     return rc;
254 }
255
256
257 /**************************************************************************
258  *              SetFileAttributes16     (KERNEL.421)
259  */
260 BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
261 {
262     return SetFileAttributes32A( lpFileName, attributes );
263 }
264
265
266 /**************************************************************************
267  *              SetFileAttributes32A    (KERNEL32.490)
268  */
269 BOOL32 WINAPI SetFileAttributes32A(LPCSTR lpFileName, DWORD attributes)
270 {
271     struct stat buf;
272     DOS_FULL_NAME full_name;
273
274     if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name ))
275         return FALSE;
276
277     TRACE(file,"(%s,%lx)\n",lpFileName,attributes);
278     if (attributes & FILE_ATTRIBUTE_NORMAL) {
279       attributes &= ~FILE_ATTRIBUTE_NORMAL;
280       if (attributes)
281         FIXME(file,"(%s):%lx illegal combination with FILE_ATTRIBUTE_NORMAL.\n",
282               lpFileName,attributes);
283     }
284     if(stat(full_name.long_name,&buf)==-1)
285     {
286         SetLastError(ErrnoToLastError(errno));
287         return FALSE;
288     }
289     if (attributes & FILE_ATTRIBUTE_READONLY)
290     {
291         buf.st_mode &= ~0222; /* octal!, clear write permission bits */
292         attributes &= ~FILE_ATTRIBUTE_READONLY;
293     }
294     attributes &= ~(FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
295     if (attributes)
296         FIXME(file,"(%s):%lx attribute(s) not implemented.\n",
297               lpFileName,attributes);
298     if (-1==chmod(full_name.long_name,buf.st_mode))
299     {
300         SetLastError(ErrnoToLastError(errno));
301         return FALSE;
302     }
303     return TRUE;
304 }
305
306
307 /**************************************************************************
308  *              SetFileAttributes32W    (KERNEL32.491)
309  */
310 BOOL32 WINAPI SetFileAttributes32W(LPCWSTR lpFileName, DWORD attributes)
311 {
312     LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
313     BOOL32 res = SetFileAttributes32A( afn, attributes );
314     HeapFree( GetProcessHeap(), 0, afn );
315     return res;
316 }
317
318
319 /**************************************************************************
320  *              SetFileApisToOEM   (KERNEL32.645)
321  */
322 VOID WINAPI SetFileApisToOEM(void)
323 {
324   /*FIXME(file,"(): stub!\n");*/
325 }
326
327
328 /**************************************************************************
329  *              SetFileApisToANSI   (KERNEL32.644)
330  */
331 VOID WINAPI SetFileApisToANSI(void)
332 {
333     /*FIXME(file,"(): stub\n");*/
334 }
335
336
337 /******************************************************************************
338  * AreFileApisANSI [KERNEL32.105]  Determines if file functions are using ANSI
339  *
340  * RETURNS
341  *    TRUE:  Set of file functions is using ANSI code page
342  *    FALSE: Set of file functions is using OEM code page
343  */
344 BOOL32 WINAPI AreFileApisANSI(void)
345 {
346     FIXME(file,"(void): stub\n");
347     return TRUE;
348 }
349