:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / kernel32 / file / create.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/file/create.c
6  * PURPOSE:         Directory functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  *                  GetTempFileName is modified from WINE [ Alexandre Juiliard ]
9  * UPDATE HISTORY:
10  *                  Created 01/11/98
11  *                  Removed use of SearchPath (not used by Windows)
12  *                  18/08/2002: CreateFileW mess cleaned up (KJK::Hyperion)
13  *                  24/08/2002: removed superfluous DPRINTs (KJK::Hyperion)
14  */
15
16 /* INCLUDES *****************************************************************/
17
18 #include <ddk/ntddk.h>
19 /* please FIXME: ddk/ntddk.h should be enough */
20 #include <ddk/iodef.h>
21 #include <ntdll/rtl.h>
22 #include <windows.h>
23
24 #define NDEBUG
25 #include <kernel32/kernel32.h>
26 #include <kernel32/error.h>
27
28
29 /* FUNCTIONS ****************************************************************/
30
31 HANDLE STDCALL CreateFileA (LPCSTR                      lpFileName,
32                             DWORD                       dwDesiredAccess,
33                             DWORD                       dwShareMode,
34                             LPSECURITY_ATTRIBUTES       lpSecurityAttributes,
35                             DWORD                       dwCreationDisposition,
36                             DWORD                       dwFlagsAndAttributes,
37                             HANDLE                      hTemplateFile)
38 {
39    UNICODE_STRING FileNameU;
40    ANSI_STRING FileName;
41    HANDLE FileHandle;
42    
43    DPRINT("CreateFileA(lpFileName %s)\n",lpFileName);
44    
45    RtlInitAnsiString (&FileName,
46                       (LPSTR)lpFileName);
47    
48    /* convert ansi (or oem) string to unicode */
49    if (bIsFileApiAnsi)
50      RtlAnsiStringToUnicodeString (&FileNameU,
51                                    &FileName,
52                                    TRUE);
53    else
54      RtlOemStringToUnicodeString (&FileNameU,
55                                   &FileName,
56                                   TRUE);
57
58    FileHandle = CreateFileW (FileNameU.Buffer,
59                              dwDesiredAccess,
60                              dwShareMode,
61                              lpSecurityAttributes,
62                              dwCreationDisposition,
63                              dwFlagsAndAttributes,
64                              hTemplateFile);
65    
66    RtlFreeHeap (RtlGetProcessHeap (),
67                 0,
68                 FileNameU.Buffer);
69    
70    return FileHandle;
71 }
72
73
74 HANDLE STDCALL CreateFileW (LPCWSTR                     lpFileName,
75                             DWORD                       dwDesiredAccess,
76                             DWORD                       dwShareMode,
77                             LPSECURITY_ATTRIBUTES       lpSecurityAttributes,
78                             DWORD                       dwCreationDisposition,
79                             DWORD                       dwFlagsAndAttributes,
80                             HANDLE                      hTemplateFile)
81 {
82    OBJECT_ATTRIBUTES ObjectAttributes;
83    IO_STATUS_BLOCK IoStatusBlock;
84    UNICODE_STRING NtPathU;
85    HANDLE FileHandle;
86    NTSTATUS Status;
87    ULONG Flags = 0;
88
89    DPRINT("CreateFileW(lpFileName %S)\n",lpFileName);
90
91    if(hTemplateFile != NULL)
92    {
93     /* FIXME */
94     DPRINT("Template file feature not supported yet\n");
95     SetLastError(ERROR_NOT_SUPPORTED);
96     return INVALID_HANDLE_VALUE;
97    }
98
99    /* validate & translate the creation disposition */
100    switch (dwCreationDisposition)
101      {
102       case CREATE_NEW:
103         dwCreationDisposition = FILE_CREATE;
104         break;
105         
106       case CREATE_ALWAYS:
107         dwCreationDisposition = FILE_OVERWRITE_IF;
108         break;
109         
110       case OPEN_EXISTING:
111         dwCreationDisposition = FILE_OPEN;
112         break;
113         
114       case OPEN_ALWAYS:
115         dwCreationDisposition = FILE_OPEN_IF;
116         break;
117
118       case TRUNCATE_EXISTING:
119         dwCreationDisposition = FILE_OVERWRITE;
120         break;
121       
122       default:
123         SetLastError(ERROR_INVALID_PARAMETER);
124         return (INVALID_HANDLE_VALUE);
125      }
126
127    /* validate & translate the flags */
128    if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
129    {
130     DPRINT("Overlapped I/O not supported\n");
131     SetLastError(ERROR_NOT_SUPPORTED);
132     return INVALID_HANDLE_VALUE;
133    }
134    else
135      Flags |= FILE_SYNCHRONOUS_IO_ALERT;
136    
137    /* validate & translate the filename */
138    if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
139                                       &NtPathU,
140                                       NULL,
141                                       NULL))
142    {
143      DPRINT("Invalid path\n");
144      SetLastError(ERROR_BAD_PATHNAME);
145      return INVALID_HANDLE_VALUE;
146    }
147    
148    DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer);
149
150    /* translate the flags that need no validation */
151    if(dwFlagsAndAttributes & FILE_FLAG_WRITE_THROUGH)
152     Flags |= FILE_WRITE_THROUGH;
153
154    if(dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
155     Flags |= FILE_NO_INTERMEDIATE_BUFFERING;
156
157    if(dwFlagsAndAttributes & FILE_FLAG_RANDOM_ACCESS)
158     Flags |= FILE_RANDOM_ACCESS;
159    
160    if(dwFlagsAndAttributes & FILE_FLAG_SEQUENTIAL_SCAN)
161     Flags |= FILE_SEQUENTIAL_ONLY;
162    
163    if(dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE)
164     Flags |= FILE_DELETE_ON_CLOSE;
165    
166    if(dwFlagsAndAttributes & FILE_FLAG_BACKUP_SEMANTICS)
167    {
168     if(dwDesiredAccess & GENERIC_ALL)
169       Flags |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_FOR_RECOVERY;
170     else
171     {
172       if(dwDesiredAccess & GENERIC_READ)
173         Flags |= FILE_OPEN_FOR_BACKUP_INTENT;
174       
175       if(dwDesiredAccess & GENERIC_WRITE)
176         Flags |= FILE_OPEN_FOR_RECOVERY;
177     }
178    }
179    else
180     Flags |= FILE_NON_DIRECTORY_FILE;
181
182    /* FILE_FLAG_POSIX_SEMANTICS is handled later */
183
184 #if 0
185    /* FIXME: Win32 constants to be defined */
186    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_REPARSE_POINT)
187     Flags |= FILE_OPEN_REPARSE_POINT;
188    
189    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_NO_RECALL)
190     Flags |= FILE_OPEN_NO_RECALL;
191 #endif
192
193    /* translate the desired access */
194    if (dwDesiredAccess & GENERIC_ALL)
195      dwDesiredAccess |= FILE_ALL_ACCESS;
196    else
197    {
198      if (dwDesiredAccess & GENERIC_READ)
199        dwDesiredAccess |= FILE_GENERIC_READ;
200      
201      if (dwDesiredAccess & GENERIC_WRITE)
202        dwDesiredAccess |= FILE_GENERIC_WRITE;
203      
204      if (dwDesiredAccess & GENERIC_EXECUTE)
205        dwDesiredAccess |= FILE_GENERIC_EXECUTE;
206    }
207
208    /* build the object attributes */
209    InitializeObjectAttributes(
210     &ObjectAttributes,
211     &NtPathU,
212     0,
213     NULL,
214     NULL
215    );
216
217    if (lpSecurityAttributes)
218    {
219       if(lpSecurityAttributes->bInheritHandle)
220          ObjectAttributes.Attributes |= OBJ_INHERIT;
221
222       ObjectAttributes.SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
223    }
224    
225    if(!(dwFlagsAndAttributes & FILE_FLAG_POSIX_SEMANTICS))
226     ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
227
228    /* perform the call */
229    Status = NtCreateFile (&FileHandle,
230                           dwDesiredAccess,
231                           &ObjectAttributes,
232                           &IoStatusBlock,
233                           NULL,
234                           dwFlagsAndAttributes,
235                           dwShareMode,
236                           dwCreationDisposition,
237                           Flags,
238                           NULL,
239                           0);
240
241    RtlFreeUnicodeString(&NtPathU);
242
243    /* error */
244    if (!NT_SUCCESS(Status))
245      {
246         SetLastErrorByStatus (Status);
247         return INVALID_HANDLE_VALUE;
248      }
249    
250    switch(IoStatusBlock.Information)
251    {
252     case FILE_OPENED:
253     case FILE_CREATED:
254      SetLastError(ERROR_ALREADY_EXISTS);
255      break;
256     
257     default:
258    }
259    
260    return FileHandle;
261 }
262
263 /* EOF */