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
,
40 DPRINT("CreateFileA(lpFileName %s)\n",lpFileName
);
42 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
43 return INVALID_HANDLE_VALUE
;
45 FileHandle
= CreateFileW (FileNameW
,
49 dwCreationDisposition
,
60 HANDLE STDCALL
CreateFileW (LPCWSTR lpFileName
,
61 DWORD dwDesiredAccess
,
63 LPSECURITY_ATTRIBUTES lpSecurityAttributes
,
64 DWORD dwCreationDisposition
,
65 DWORD dwFlagsAndAttributes
,
68 OBJECT_ATTRIBUTES ObjectAttributes
;
69 IO_STATUS_BLOCK IoStatusBlock
;
70 UNICODE_STRING NtPathU
;
74 CSRSS_API_REQUEST Request
;
75 CSRSS_API_REPLY Reply
;
77 DPRINT("CreateFileW(lpFileName %S)\n",lpFileName
);
79 if(hTemplateFile
!= NULL
&& hTemplateFile
!= INVALID_HANDLE_VALUE
)
82 DPRINT1("Template file feature not supported yet\n");
83 SetLastError(ERROR_NOT_SUPPORTED
);
84 return INVALID_HANDLE_VALUE
;
87 /* validate & translate the creation disposition */
88 switch (dwCreationDisposition
)
91 dwCreationDisposition
= FILE_CREATE
;
95 dwCreationDisposition
= FILE_OVERWRITE_IF
;
99 dwCreationDisposition
= FILE_OPEN
;
103 dwCreationDisposition
= FILE_OPEN_IF
;
106 case TRUNCATE_EXISTING
:
107 dwCreationDisposition
= FILE_OVERWRITE
;
111 SetLastError(ERROR_INVALID_PARAMETER
);
112 return (INVALID_HANDLE_VALUE
);
115 /* validate & translate the filename */
116 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
121 DPRINT("Invalid path\n");
122 SetLastError(ERROR_PATH_NOT_FOUND
);
123 return INVALID_HANDLE_VALUE
;
126 DPRINT("NtPathU \'%S\'\n", NtPathU
.Buffer
);
128 /* validate & translate the flags */
130 /* translate the flags that need no validation */
131 if (!(dwFlagsAndAttributes
& FILE_FLAG_OVERLAPPED
)){
132 /* yes, nonalert is correct! apc's are not delivered
133 while waiting for file io to complete */
134 Flags
|= FILE_SYNCHRONOUS_IO_NONALERT
;
137 if(dwFlagsAndAttributes
& FILE_FLAG_WRITE_THROUGH
)
138 Flags
|= FILE_WRITE_THROUGH
;
140 if(dwFlagsAndAttributes
& FILE_FLAG_NO_BUFFERING
)
141 Flags
|= FILE_NO_INTERMEDIATE_BUFFERING
;
143 if(dwFlagsAndAttributes
& FILE_FLAG_RANDOM_ACCESS
)
144 Flags
|= FILE_RANDOM_ACCESS
;
146 if(dwFlagsAndAttributes
& FILE_FLAG_SEQUENTIAL_SCAN
)
147 Flags
|= FILE_SEQUENTIAL_ONLY
;
149 if(dwFlagsAndAttributes
& FILE_FLAG_DELETE_ON_CLOSE
)
150 Flags
|= FILE_DELETE_ON_CLOSE
;
152 if(dwFlagsAndAttributes
& FILE_FLAG_BACKUP_SEMANTICS
)
154 if(dwDesiredAccess
& GENERIC_ALL
)
155 Flags
|= FILE_OPEN_FOR_BACKUP_INTENT
| FILE_OPEN_FOR_RECOVERY
;
158 if(dwDesiredAccess
& GENERIC_READ
)
159 Flags
|= FILE_OPEN_FOR_BACKUP_INTENT
;
161 if(dwDesiredAccess
& GENERIC_WRITE
)
162 Flags
|= FILE_OPEN_FOR_RECOVERY
;
166 Flags
|= FILE_NON_DIRECTORY_FILE
;
169 /* handle may allways be waited on and querying attributes are allways allowed */
170 dwDesiredAccess
|= SYNCHRONIZE
|FILE_READ_ATTRIBUTES
;
172 /* FILE_FLAG_POSIX_SEMANTICS is handled later */
175 /* FIXME: Win32 constants to be defined */
176 if(dwFlagsAndAttributes
& FILE_FLAG_OPEN_REPARSE_POINT
)
177 Flags
|= FILE_OPEN_REPARSE_POINT
;
179 if(dwFlagsAndAttributes
& FILE_FLAG_OPEN_NO_RECALL
)
180 Flags
|= FILE_OPEN_NO_RECALL
;
183 /* check for console output */
184 if (0 == _wcsicmp(L
"CONOUT$", lpFileName
))
186 /* FIXME: Send required access rights to Csrss */
187 Request
.Type
= CSRSS_GET_OUTPUT_HANDLE
;
188 Status
= CsrClientCallServer(&Request
,
190 sizeof(CSRSS_API_REQUEST
),
191 sizeof(CSRSS_API_REPLY
));
192 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Reply
.Status
))
194 SetLastErrorByStatus(Status
);
195 return INVALID_HANDLE_VALUE
;
199 return Reply
.Data
.GetOutputHandleReply
.OutputHandle
;
203 /* check for console input */
204 if (0 == _wcsicmp(L
"CONIN$", lpFileName
))
206 /* FIXME: Send required access rights to Csrss */
207 Request
.Type
= CSRSS_GET_INPUT_HANDLE
;
208 Status
= CsrClientCallServer(&Request
,
210 sizeof(CSRSS_API_REQUEST
),
211 sizeof(CSRSS_API_REPLY
));
212 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Reply
.Status
))
214 SetLastErrorByStatus(Status
);
215 return INVALID_HANDLE_VALUE
;
219 return Reply
.Data
.GetInputHandleReply
.InputHandle
;
223 /* build the object attributes */
224 InitializeObjectAttributes(
232 if (lpSecurityAttributes
)
234 if(lpSecurityAttributes
->bInheritHandle
)
235 ObjectAttributes
.Attributes
|= OBJ_INHERIT
;
237 ObjectAttributes
.SecurityDescriptor
= lpSecurityAttributes
->lpSecurityDescriptor
;
240 if(!(dwFlagsAndAttributes
& FILE_FLAG_POSIX_SEMANTICS
))
241 ObjectAttributes
.Attributes
|= OBJ_CASE_INSENSITIVE
;
243 /* perform the call */
244 Status
= NtCreateFile (&FileHandle
,
249 dwFlagsAndAttributes
,
251 dwCreationDisposition
,
256 RtlFreeUnicodeString(&NtPathU
);
259 if (!NT_SUCCESS(Status
))
261 /* In the case file creation was rejected due to CREATE_NEW flag
262 * was specified and file with that name already exists, correct
263 * last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
264 * Note: RtlNtStatusToDosError is not the subject to blame here.
266 if (Status
== STATUS_OBJECT_NAME_COLLISION
&&
267 dwCreationDisposition
== FILE_CREATE
)
269 SetLastError( ERROR_FILE_EXISTS
);
273 SetLastErrorByStatus (Status
);
276 return INVALID_HANDLE_VALUE
;
280 create with OPEN_ALWAYS (FILE_OPEN_IF) returns info = FILE_OPENED or FILE_CREATED
281 create with CREATE_ALWAYS (FILE_OVERWRITE_IF) returns info = FILE_OVERWRITTEN or FILE_CREATED
283 if (dwCreationDisposition
== FILE_OPEN_IF
)
285 SetLastError(IoStatusBlock
.Information
== FILE_OPENED
? ERROR_ALREADY_EXISTS
: 0);
287 else if (dwCreationDisposition
== FILE_OVERWRITE_IF
)
289 SetLastError(IoStatusBlock
.Information
== FILE_OVERWRITTEN
? ERROR_ALREADY_EXISTS
: 0);