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