incorrect use of FILE_xxx defines, not avalaible for CreateFile ?
[reactos.git] / reactos / lib / msvcrt / io / open.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/crtdll/io/open.c
5 * PURPOSE: Opens a file and translates handles to fileno
6 * PROGRAMER: Boudewijn Dekker
7 * UPDATE HISTORY:
8 * 28/12/98: Created
9 */
10
11 // rember to interlock the allocation of fileno when making this thread safe
12
13 // possibly store extra information at the handle
14
15 #include <windows.h>
16 #include <crtdll/io.h>
17 #include <crtdll/fcntl.h>
18 #include <crtdll/sys/stat.h>
19 #include <crtdll/stdlib.h>
20 #include <crtdll/internal/file.h>
21 #include <crtdll/string.h>
22 #include <crtdll/share.h>
23
24 typedef struct _fileno_modes_type
25 {
26 HANDLE hFile;
27 int mode;
28 int fd;
29 } fileno_modes_type;
30
31 fileno_modes_type *fileno_modes = NULL;
32
33 int maxfno = 5;
34 int minfno = 5;
35
36 char __is_text_file(FILE *p)
37 {
38 if ( p == NULL || fileno_modes == NULL )
39 return FALSE;
40 return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT));
41 }
42
43
44 int __fileno_alloc(HANDLE hFile, int mode);
45
46
47 int _open(const char *_path, int _oflag,...)
48 {
49 HANDLE hFile;
50 DWORD dwDesiredAccess = 0;
51 DWORD dwShareMode = 0;
52 DWORD dwCreationDistribution = 0;
53 DWORD dwFlagsAndAttributes = 0;
54
55 if (( _oflag & S_IREAD ) == S_IREAD)
56 dwShareMode = FILE_SHARE_READ;
57 else if ( ( _oflag & S_IWRITE) == S_IWRITE ) {
58 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
59 }
60
61 /*
62 *
63 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
64 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
65 *
66 * _O_APPEND Moves file pointer to end of file before every write operation.
67 */
68 if (( _oflag & _O_RDWR ) == _O_RDWR )
69 dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ ;
70 else if (( _oflag & O_RDONLY ) == O_RDONLY )
71 dwDesiredAccess |= GENERIC_READ ;
72 else if (( _oflag & _O_WRONLY ) == _O_WRONLY )
73 dwDesiredAccess |= GENERIC_WRITE ;
74
75 if (( _oflag & S_IREAD ) == S_IREAD )
76 dwShareMode |= FILE_SHARE_READ;
77
78 if (( _oflag & S_IWRITE ) == S_IWRITE )
79 dwShareMode |= FILE_SHARE_WRITE;
80
81 if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) )
82 dwCreationDistribution |= CREATE_NEW;
83
84 else if (( _oflag & O_TRUNC ) == O_TRUNC ) {
85 if (( _oflag & O_CREAT ) == O_CREAT )
86 dwCreationDistribution |= CREATE_ALWAYS;
87 else if (( _oflag & O_RDONLY ) != O_RDONLY )
88 dwCreationDistribution |= TRUNCATE_EXISTING;
89 }
90 else if (( _oflag & _O_APPEND ) == _O_APPEND )
91 dwCreationDistribution |= OPEN_EXISTING;
92 else if (( _oflag & _O_CREAT ) == _O_CREAT )
93 dwCreationDistribution |= OPEN_ALWAYS;
94 else
95 dwCreationDistribution |= OPEN_EXISTING;
96
97 if (( _oflag & _O_RANDOM ) == _O_RANDOM )
98 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
99 if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL )
100 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
101
102 if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY )
103 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
104
105 if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
106 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
107
108 hFile = CreateFileA(_path,
109 dwDesiredAccess,
110 dwShareMode,
111 NULL,
112 dwCreationDistribution,
113 dwFlagsAndAttributes,
114 NULL);
115 if (hFile == (HANDLE)-1)
116 return -1;
117 return __fileno_alloc(hFile,_oflag);
118 }
119
120
121 int _wopen(const wchar_t *_path, int _oflag,...)
122 {
123 HANDLE hFile;
124 DWORD dwDesiredAccess = 0;
125 DWORD dwShareMode = 0;
126 DWORD dwCreationDistribution = 0;
127 DWORD dwFlagsAndAttributes = 0;
128
129 if (( _oflag & S_IREAD ) == S_IREAD)
130 dwShareMode = FILE_SHARE_READ;
131 else if ( ( _oflag & S_IWRITE) == S_IWRITE ) {
132 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
133 }
134
135 /*
136 *
137 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
138 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
139 *
140 * _O_APPEND Moves file pointer to end of file before every write operation.
141 */
142 if (( _oflag & _O_RDWR ) == _O_RDWR )
143 dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA |
144 FILE_WRITE_DATA | FILE_READ_ATTRIBUTES |
145 FILE_WRITE_ATTRIBUTES;
146 else if (( _oflag & O_RDONLY ) == O_RDONLY )
147 dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES
148 | FILE_WRITE_ATTRIBUTES;
149 else if (( _oflag & _O_WRONLY ) == _O_WRONLY )
150 dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA |
151 FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES;
152
153 if (( _oflag & S_IREAD ) == S_IREAD )
154 dwShareMode |= FILE_SHARE_READ;
155
156 if (( _oflag & S_IWRITE ) == S_IWRITE )
157 dwShareMode |= FILE_SHARE_WRITE;
158
159 if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) )
160 dwCreationDistribution |= CREATE_NEW;
161
162 else if (( _oflag & O_TRUNC ) == O_TRUNC ) {
163 if (( _oflag & O_CREAT ) == O_CREAT )
164 dwCreationDistribution |= CREATE_ALWAYS;
165 else if (( _oflag & O_RDONLY ) != O_RDONLY )
166 dwCreationDistribution |= TRUNCATE_EXISTING;
167 }
168 else if (( _oflag & _O_APPEND ) == _O_APPEND )
169 dwCreationDistribution |= OPEN_EXISTING;
170 else if (( _oflag & _O_CREAT ) == _O_CREAT )
171 dwCreationDistribution |= OPEN_ALWAYS;
172 else
173 dwCreationDistribution |= OPEN_EXISTING;
174
175 if (( _oflag & _O_RANDOM ) == _O_RANDOM )
176 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
177 if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL )
178 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
179
180 if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY )
181 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
182
183 if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
184 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
185
186 hFile = CreateFileW(_path,
187 dwDesiredAccess,
188 dwShareMode,
189 NULL,
190 dwCreationDistribution,
191 dwFlagsAndAttributes,
192 NULL);
193 if (hFile == (HANDLE)-1)
194 return -1;
195 return __fileno_alloc(hFile,_oflag);
196 }
197
198
199 int
200 __fileno_alloc(HANDLE hFile, int mode)
201 {
202 int i;
203 /* Check for bogus values */
204 if (hFile < 0)
205 return -1;
206
207 for(i=minfno;i<maxfno;i++) {
208 if (fileno_modes[i].fd == -1 ) {
209 fileno_modes[i].fd = i;
210 fileno_modes[i].mode = mode;
211 fileno_modes[i].hFile = hFile;
212 return i;
213 }
214 }
215
216 /* See if we need to expand the tables. Check this BEFORE it might fail,
217 so that when we hit the count'th request, we've already up'd it. */
218 if ( i == maxfno)
219 {
220 int oldcount = maxfno;
221 fileno_modes_type *old_fileno_modes = fileno_modes;
222 maxfno += 255;
223 fileno_modes = (fileno_modes_type *)malloc(maxfno * sizeof(fileno_modes_type));
224 if ( old_fileno_modes != NULL )
225 memcpy(fileno_modes, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
226 memset(fileno_modes + oldcount, 0, (maxfno-oldcount)*sizeof(fileno_modes));
227 free ( old_fileno_modes );
228 }
229
230 /* Fill in the value */
231 fileno_modes[i].fd = i;
232 fileno_modes[i].mode = mode;
233 fileno_modes[i].hFile = hFile;
234 return i;
235 }
236
237 void *filehnd(int fileno)
238 {
239 if ( fileno < 0 )
240 return (void *)-1;
241 #define STD_AUX_HANDLE 3
242 #define STD_PRINTER_HANDLE 4
243
244 switch(fileno)
245 {
246 case 0:
247 return GetStdHandle(STD_INPUT_HANDLE);
248 case 1:
249 return GetStdHandle(STD_OUTPUT_HANDLE);
250 case 2:
251 return GetStdHandle(STD_ERROR_HANDLE);
252 case 3:
253 return GetStdHandle(STD_AUX_HANDLE);
254 case 4:
255 return GetStdHandle(STD_PRINTER_HANDLE);
256 default:
257 break;
258 }
259
260 if ( fileno >= maxfno )
261 return (void *)-1;
262
263 if ( fileno_modes[fileno].fd == -1 )
264 return (void *)-1;
265 return fileno_modes[fileno].hFile;
266 }
267
268 int __fileno_dup2( int handle1, int handle2 )
269 {
270 if ( handle1 >= maxfno )
271 return -1;
272
273 if ( handle1 < 0 )
274 return -1;
275 if ( handle2 >= maxfno )
276 return -1;
277
278 if ( handle2 < 0 )
279 return -1;
280
281 memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes));
282
283 return handle1;
284 }
285
286 int __fileno_setmode(int _fd, int _newmode)
287 {
288 int m;
289 if ( _fd < minfno )
290 return -1;
291
292 if ( _fd >= maxfno )
293 return -1;
294
295 m = fileno_modes[_fd].mode;
296 fileno_modes[_fd].mode = _newmode;
297 return m;
298 }
299
300 int __fileno_getmode(int _fd)
301 {
302 if ( _fd < minfno )
303 return -1;
304
305 if ( _fd >= maxfno )
306 return -1;
307
308 return fileno_modes[_fd].mode;
309
310 }
311
312
313 int __fileno_close(int _fd)
314 {
315 if ( _fd < 0 )
316 return -1;
317
318 if ( _fd >= maxfno )
319 return -1;
320
321 fileno_modes[_fd].fd = -1;
322 fileno_modes[_fd].hFile = (HANDLE)-1;
323 return 0;
324 }
325
326 int _open_osfhandle (void *osfhandle, int flags )
327 {
328 return __fileno_alloc((HANDLE)osfhandle, flags);
329 }
330
331 void *_get_osfhandle( int fileno )
332 {
333 return filehnd(fileno);
334 }