Fixed header inclusion order.
[reactos.git] / reactos / ntoskrnl / io / create.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/create.c
5 * PURPOSE: Handling file create/open apis
6 * PROGRAMMER: David Welch (welch@cwcom.net)
7 * UPDATE HISTORY:
8 * 24/05/98: Created
9 */
10
11 /* INCLUDES ***************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
15 #include <internal/io.h>
16 #include <internal/id.h>
17 #include <internal/string.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* FUNCTIONS *************************************************************/
23
24 NTSTATUS
25 STDCALL
26 NtDeleteFile (
27 IN POBJECT_ATTRIBUTES ObjectAttributes
28 )
29 {
30 UNIMPLEMENTED;
31 }
32
33
34 NTSTATUS IopCreateFile(PVOID ObjectBody,
35 PVOID Parent,
36 PWSTR RemainingPath,
37 POBJECT_ATTRIBUTES ObjectAttributes)
38 {
39 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parent;
40 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
41 NTSTATUS Status;
42
43 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %w)\n",
44 ObjectBody,Parent,RemainingPath);
45
46 if (DeviceObject == NULL)
47 {
48 return(STATUS_SUCCESS);
49 }
50
51 Status = ObReferenceObjectByPointer(DeviceObject,
52 STANDARD_RIGHTS_REQUIRED,
53 IoDeviceType,
54 UserMode);
55 if (Status != STATUS_SUCCESS)
56 {
57 CHECKPOINT;
58 return(Status);
59 }
60
61 DeviceObject = IoGetAttachedDevice(DeviceObject);
62
63 DPRINT("DeviceObject %x\n",DeviceObject);
64
65 if (RemainingPath == NULL)
66 {
67 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
68 FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
69 (ObjectAttributes->ObjectName->Length+1)*2);
70 FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
71 FileObject->FileName.MaximumLength =
72 ObjectAttributes->ObjectName->MaximumLength;
73 RtlCopyUnicodeString(&(FileObject->FileName),
74 ObjectAttributes->ObjectName);
75 }
76 else
77 {
78 if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM &&
79 DeviceObject->DeviceType != FILE_DEVICE_DISK)
80 {
81 return(STATUS_UNSUCCESSFUL);
82 }
83 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
84 {
85 Status = IoTryToMountStorageDevice(DeviceObject);
86 if (Status!=STATUS_SUCCESS)
87 {
88 return(Status);
89 }
90 DeviceObject = IoGetAttachedDevice(DeviceObject);
91 }
92 RtlInitUnicodeString(&(FileObject->FileName),wcsdup(RemainingPath));
93 }
94 DPRINT("FileObject->FileName.Buffer %w\n",FileObject->FileName.Buffer);
95 FileObject->DeviceObject = DeviceObject;
96 FileObject->Vpb = DeviceObject->Vpb;
97 FileObject->Type = ID_FILE_OBJECT;
98
99 return(STATUS_SUCCESS);
100 }
101
102 PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
103 PDEVICE_OBJECT DeviceObject)
104 {
105 HANDLE FileHandle;
106 PFILE_OBJECT CreatedFileObject;
107
108 DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
109 FileObject, DeviceObject);
110
111 assert_irql(PASSIVE_LEVEL);
112
113 CreatedFileObject = ObCreateObject(&FileHandle,
114 STANDARD_RIGHTS_REQUIRED,
115 NULL,
116 IoFileType);
117 if (CreatedFileObject == NULL)
118 {
119 return(NULL);
120 }
121
122 if (FileObject != NULL)
123 {
124 DeviceObject = FileObject->DeviceObject;
125 }
126 DeviceObject = IoGetAttachedDevice(DeviceObject);
127 CreatedFileObject->DeviceObject = DeviceObject;
128 CreatedFileObject->Vpb = DeviceObject->Vpb;
129 CreatedFileObject->Type = ID_FILE_OBJECT;
130 CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
131
132 ZwClose(FileHandle);
133
134 return(CreatedFileObject);
135 }
136
137 NTSTATUS
138 STDCALL
139 NtCreateFile (
140 PHANDLE FileHandle,
141 ACCESS_MASK DesiredAccess,
142 POBJECT_ATTRIBUTES ObjectAttributes,
143 PIO_STATUS_BLOCK IoStatusBlock,
144 PLARGE_INTEGER AllocateSize,
145 ULONG FileAttributes,
146 ULONG ShareAccess,
147 ULONG CreateDisposition,
148 ULONG CreateOptions,
149 PVOID EaBuffer,
150 ULONG EaLength
151 )
152 /*
153 * FUNCTION: Either causes a new file or directory to be created, or it opens
154 * an existing file, device, directory or volume, giving the caller a handle
155 * for the file object. This handle can be used by subsequent calls to
156 * manipulate data within the file or the file object's state of attributes.
157 * ARGUMENTS:
158 * FileHandle (OUT) = Points to a variable which receives the file
159 * handle on return
160 * DesiredAccess = Desired access to the file
161 * ObjectAttributes = Structure describing the file
162 * IoStatusBlock (OUT) = Receives information about the operation on
163 * return
164 * AllocationSize = Initial size of the file in bytes
165 * FileAttributes = Attributes to create the file with
166 * ShareAccess = Type of shared access the caller would like to the file
167 * CreateDisposition = Specifies what to do, depending on whether the
168 * file already exists
169 * CreateOptions = Options for creating a new file
170 * EaBuffer = Undocumented
171 * EaLength = Undocumented
172 * RETURNS: Status
173 */
174 {
175 PFILE_OBJECT FileObject;
176 NTSTATUS Status;
177 PIRP Irp;
178 KEVENT Event;
179 PIO_STACK_LOCATION StackLoc;
180
181 DPRINT("NtCreateFile(FileHandle %x, DesiredAccess %x, "
182 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %w)\n",
183 FileHandle,DesiredAccess,ObjectAttributes,
184 ObjectAttributes->ObjectName->Buffer);
185
186 assert_irql(PASSIVE_LEVEL);
187
188 *FileHandle=0;
189
190 FileObject = ObCreateObject(FileHandle,
191 DesiredAccess,
192 ObjectAttributes,
193 IoFileType);
194 if (FileObject == NULL)
195 {
196 return(STATUS_UNSUCCESSFUL);
197 }
198
199 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
200 {
201 FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO;
202 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
203 }
204 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
205 {
206 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
207 }
208
209 KeInitializeEvent(&Event, NotificationEvent, FALSE);
210
211 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
212 if (Irp==NULL)
213 {
214 return(STATUS_UNSUCCESSFUL);
215 }
216
217 StackLoc = IoGetNextIrpStackLocation(Irp);
218 StackLoc->MajorFunction = IRP_MJ_CREATE;
219 StackLoc->MinorFunction = 0;
220 StackLoc->Flags = 0;
221 StackLoc->Control = 0;
222 StackLoc->DeviceObject = FileObject->DeviceObject;
223 StackLoc->FileObject = FileObject;
224 StackLoc->Parameters.Create.Options = CreateOptions&FILE_VALID_OPTION_FLAGS;
225 StackLoc->Parameters.Create.Options |= CreateDisposition<<24;
226
227 Status = IoCallDriver(FileObject->DeviceObject,Irp);
228 if (Status == STATUS_PENDING)
229 {
230 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
231 Status = IoStatusBlock->Status;
232 }
233
234 if (!NT_SUCCESS(Status))
235 {
236 DPRINT("Failing create request with status %x\n",Status);
237 ZwClose(*FileHandle);
238 (*FileHandle) = 0;
239 }
240
241 assert_irql(PASSIVE_LEVEL);
242 DPRINT("Finished NtCreateFile() (*FileHandle) %x\n",(*FileHandle));
243 return(Status);
244 }
245
246
247 NTSTATUS
248 STDCALL
249 NtOpenFile (
250 PHANDLE FileHandle,
251 ACCESS_MASK DesiredAccess,
252 POBJECT_ATTRIBUTES ObjectAttributes,
253 PIO_STATUS_BLOCK IoStatusBlock,
254 ULONG ShareAccess,
255 ULONG OpenOptions
256 )
257 /*
258 * FUNCTION: Opens a file (simpler than ZwCreateFile)
259 * ARGUMENTS:
260 * FileHandle (OUT) = Variable that receives the file handle on return
261 * DesiredAccess = Access desired by the caller to the file
262 * ObjectAttributes = Structue describing the file to be opened
263 * IoStatusBlock (OUT) = Receives details about the result of the
264 * operation
265 * ShareAccess = Type of shared access the caller requires
266 * OpenOptions = Options for the file open
267 * RETURNS: Status
268 * NOTE: Undocumented
269 */
270 {
271 return(ZwCreateFile(
272 FileHandle,
273 DesiredAccess,
274 ObjectAttributes,
275 IoStatusBlock,
276 NULL,
277 0,
278 ShareAccess,
279 FILE_OPEN,
280 OpenOptions,
281 NULL,
282 0));
283 }
284
285