1 /* $Id: create.c,v 1.37 2004/07/18 17:08:29 navaraf Exp $
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 ]
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)
16 /* INCLUDES *****************************************************************/
21 #include "../include/debug.h"
24 /* FUNCTIONS ****************************************************************/
29 HANDLE STDCALL
CreateFileA (LPCSTR lpFileName
,
30 DWORD dwDesiredAccess
,
32 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
33 DWORD dwCreationDisposition
,
34 DWORD dwFlagsAndAttributes
,
37 UNICODE_STRING FileNameU
;
41 DPRINT("CreateFileA(lpFileName %s)\n",lpFileName
);
43 RtlInitAnsiString (&FileName
,
46 /* convert ansi (or oem) string to unicode */
48 RtlAnsiStringToUnicodeString (&FileNameU
,
52 RtlOemStringToUnicodeString (&FileNameU
,
56 FileHandle
= CreateFileW (FileNameU
.Buffer
,
60 dwCreationDisposition
,
64 RtlFreeHeap (RtlGetProcessHeap (),
75 HANDLE STDCALL
CreateFileW (LPCWSTR lpFileName
,
76 DWORD dwDesiredAccess
,
78 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
79 DWORD dwCreationDisposition
,
80 DWORD dwFlagsAndAttributes
,
83 OBJECT_ATTRIBUTES ObjectAttributes
;
84 IO_STATUS_BLOCK IoStatusBlock
;
85 UNICODE_STRING NtPathU
;
89 ULONG DesiredAccess
= 0;
90 CSRSS_API_REQUEST Request
;
91 CSRSS_API_REPLY Reply
;
93 DPRINT("CreateFileW(lpFileName %S)\n",lpFileName
);
95 if(hTemplateFile
!= NULL
)
98 DPRINT("Template file feature not supported yet\n");
99 SetLastError(ERROR_NOT_SUPPORTED
);
100 return INVALID_HANDLE_VALUE
;
103 /* validate & translate the creation disposition */
104 switch (dwCreationDisposition
)
107 dwCreationDisposition
= FILE_CREATE
;
111 dwCreationDisposition
= FILE_OVERWRITE_IF
;
115 dwCreationDisposition
= FILE_OPEN
;
119 dwCreationDisposition
= FILE_OPEN_IF
;
122 case TRUNCATE_EXISTING
:
123 dwCreationDisposition
= FILE_OVERWRITE
;
127 SetLastError(ERROR_INVALID_PARAMETER
);
128 return (INVALID_HANDLE_VALUE
);
131 /* validate & translate the filename */
132 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
137 DPRINT("Invalid path\n");
138 SetLastError(ERROR_BAD_PATHNAME
);
139 return INVALID_HANDLE_VALUE
;
142 DPRINT("NtPathU \'%S\'\n", NtPathU
.Buffer
);
144 /* validate & translate the flags */
146 /* translate the flags that need no validation */
147 if (!(dwFlagsAndAttributes
& FILE_FLAG_OVERLAPPED
)){
148 /* yes, nonalert is correct! apc's are not delivered
149 while waiting for file io to complete */
150 Flags
|= FILE_SYNCHRONOUS_IO_NONALERT
;
153 if(dwFlagsAndAttributes
& FILE_FLAG_WRITE_THROUGH
)
154 Flags
|= FILE_WRITE_THROUGH
;
156 if(dwFlagsAndAttributes
& FILE_FLAG_NO_BUFFERING
)
157 Flags
|= FILE_NO_INTERMEDIATE_BUFFERING
;
159 if(dwFlagsAndAttributes
& FILE_FLAG_RANDOM_ACCESS
)
160 Flags
|= FILE_RANDOM_ACCESS
;
162 if(dwFlagsAndAttributes
& FILE_FLAG_SEQUENTIAL_SCAN
)
163 Flags
|= FILE_SEQUENTIAL_ONLY
;
165 if(dwFlagsAndAttributes
& FILE_FLAG_DELETE_ON_CLOSE
)
166 Flags
|= FILE_DELETE_ON_CLOSE
;
168 if(dwFlagsAndAttributes
& FILE_FLAG_BACKUP_SEMANTICS
)
170 if(dwDesiredAccess
& GENERIC_ALL
)
171 Flags
|= FILE_OPEN_FOR_BACKUP_INTENT
| FILE_OPEN_FOR_RECOVERY
;
174 if(dwDesiredAccess
& GENERIC_READ
)
175 Flags
|= FILE_OPEN_FOR_BACKUP_INTENT
;
177 if(dwDesiredAccess
& GENERIC_WRITE
)
178 Flags
|= FILE_OPEN_FOR_RECOVERY
;
183 Flags
|= FILE_NON_DIRECTORY_FILE
;
186 if(dwDesiredAccess
& GENERIC_ALL
)
187 DesiredAccess
|= FILE_READ_DATA
| FILE_WRITE_DATA
;
190 if(dwDesiredAccess
& GENERIC_READ
)
191 DesiredAccess
|= FILE_READ_DATA
;
193 if(dwDesiredAccess
& GENERIC_WRITE
)
194 DesiredAccess
|= FILE_WRITE_DATA
;
197 /* handle may allways be waited on and querying attributes are allways allowed */
198 DesiredAccess
|= SYNCHRONIZE
|FILE_READ_ATTRIBUTES
;
200 /* FILE_FLAG_POSIX_SEMANTICS is handled later */
203 /* FIXME: Win32 constants to be defined */
204 if(dwFlagsAndAttributes
& FILE_FLAG_OPEN_REPARSE_POINT
)
205 Flags
|= FILE_OPEN_REPARSE_POINT
;
207 if(dwFlagsAndAttributes
& FILE_FLAG_OPEN_NO_RECALL
)
208 Flags
|= FILE_OPEN_NO_RECALL
;
211 /* check for console output */
212 if (0 == _wcsicmp(L
"CONOUT$", lpFileName
))
214 /* FIXME: Send required access rights to Csrss */
215 Request
.Type
= CSRSS_GET_OUTPUT_HANDLE
;
216 Status
= CsrClientCallServer(&Request
,
218 sizeof(CSRSS_API_REQUEST
),
219 sizeof(CSRSS_API_REPLY
));
220 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Reply
.Status
))
222 SetLastErrorByStatus(Status
);
223 return INVALID_HANDLE_VALUE
;
227 return Reply
.Data
.GetOutputHandleReply
.OutputHandle
;
231 /* check for console input */
232 if (0 == _wcsicmp(L
"CONIN$", lpFileName
))
234 /* FIXME: Send required access rights to Csrss */
235 Request
.Type
= CSRSS_GET_INPUT_HANDLE
;
236 Status
= CsrClientCallServer(&Request
,
238 sizeof(CSRSS_API_REQUEST
),
239 sizeof(CSRSS_API_REPLY
));
240 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Reply
.Status
))
242 SetLastErrorByStatus(Status
);
243 return INVALID_HANDLE_VALUE
;
247 return Reply
.Data
.GetInputHandleReply
.InputHandle
;
251 /* build the object attributes */
252 InitializeObjectAttributes(
260 if (lpSecurityAttributes
)
262 if(lpSecurityAttributes
->bInheritHandle
)
263 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
265 ObjectAttributes
.SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
268 if(!(dwFlagsAndAttributes
& FILE_FLAG_POSIX_SEMANTICS
))
269 ObjectAttributes
.Attributes
|= OBJ_CASE_INSENSITIVE
;
271 /* perform the call */
272 Status
= NtCreateFile (&FileHandle
,
277 dwFlagsAndAttributes
,
279 dwCreationDisposition
,
284 RtlFreeUnicodeString(&NtPathU
);
287 if (!NT_SUCCESS(Status
))
289 SetLastErrorByStatus (Status
);
290 return INVALID_HANDLE_VALUE
;
294 create with OPEN_ALWAYS (FILE_OPEN_IF) returns info = FILE_OPENED or FILE_CREATED
295 create with CREATE_ALWAYS (FILE_OVERWRITE_IF) returns info = FILE_OVERWRITTEN or FILE_CREATED
297 if ((dwCreationDisposition
== FILE_OPEN_IF
&& IoStatusBlock
.Information
== FILE_OPENED
) ||
298 (dwCreationDisposition
== FILE_OVERWRITE_IF
&& IoStatusBlock
.Information
== FILE_OVERWRITTEN
))
300 SetLastError(ERROR_ALREADY_EXISTS
);