Fixed bug in IO manager that caused crash when trying to open a file on a non existan...
[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 STDCALL NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
25 {
26 UNIMPLEMENTED;
27 }
28
29
30 NTSTATUS
31 STDCALL
32 IoCreateFile (
33 OUT PHANDLE FileHandle,
34 IN ACCESS_MASK DesiredAccess,
35 IN POBJECT_ATTRIBUTES ObjectAttributes,
36 OUT PIO_STATUS_BLOCK IoStatusBlock,
37 IN PLARGE_INTEGER AllocationSize OPTIONAL,
38 IN ULONG FileAttributes,
39 IN ULONG ShareAccess,
40 IN ULONG CreateDisposition,
41 IN ULONG CreateOptions,
42 IN PVOID EaBuffer OPTIONAL,
43 IN ULONG EaLength,
44 IN CREATE_FILE_TYPE CreateFileType,
45 IN ULONG ExtraCreateParameters,
46 IN ULONG Options
47 )
48 {
49 UNIMPLEMENTED;
50 }
51
52
53 NTSTATUS IopCreateFile(PVOID ObjectBody,
54 PVOID Parent,
55 PWSTR RemainingPath,
56 POBJECT_ATTRIBUTES ObjectAttributes)
57 {
58 PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parent;
59 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
60 NTSTATUS Status;
61
62 DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
63 ObjectBody,Parent,RemainingPath);
64
65 if (DeviceObject == NULL)
66 {
67 DPRINT("DeviceObject was NULL\n");
68 return(STATUS_SUCCESS);
69 }
70 if( BODY_TO_HEADER( Parent )->ObjectType != IoDeviceType )
71 {
72 DPRINT( "Parent is not a device type\n" );
73 return STATUS_UNSUCCESSFUL;
74 }
75 Status = ObReferenceObjectByPointer(DeviceObject,
76 STANDARD_RIGHTS_REQUIRED,
77 IoDeviceType,
78 UserMode);
79 if (Status != STATUS_SUCCESS)
80 {
81 CHECKPOINT;
82 return(Status);
83 }
84
85 DeviceObject = IoGetAttachedDevice(DeviceObject);
86
87 DPRINT("DeviceObject %x\n",DeviceObject);
88
89 if (RemainingPath == NULL)
90 {
91 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
92 FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
93 (ObjectAttributes->ObjectName->Length+1)*2);
94 FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
95 FileObject->FileName.MaximumLength =
96 ObjectAttributes->ObjectName->MaximumLength;
97 RtlCopyUnicodeString(&(FileObject->FileName),
98 ObjectAttributes->ObjectName);
99 }
100 else
101 {
102 if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM &&
103 DeviceObject->DeviceType != FILE_DEVICE_DISK)
104 {
105 DPRINT("Device was wrong type\n");
106 return(STATUS_UNSUCCESSFUL);
107 }
108 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
109 {
110 DPRINT("Trying to mount storage device\n");
111 Status = IoTryToMountStorageDevice(DeviceObject);
112 DPRINT("Status %x\n", Status);
113 if (!NT_SUCCESS(Status))
114 {
115 DPRINT("Failed to mount storage device (statux %x)\n",
116 Status);
117 return(Status);
118 }
119 DeviceObject = IoGetAttachedDevice(DeviceObject);
120 }
121 RtlInitUnicodeString(&(FileObject->FileName),wcsdup(RemainingPath));
122 }
123 DPRINT("FileObject->FileName.Buffer %S\n",FileObject->FileName.Buffer);
124 FileObject->DeviceObject = DeviceObject;
125 DPRINT("FileObject %x DeviceObject %x\n", FileObject, DeviceObject);
126 FileObject->Vpb = DeviceObject->Vpb;
127 FileObject->Type = InternalFileType;
128
129 return(STATUS_SUCCESS);
130 }
131
132 PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
133 PDEVICE_OBJECT DeviceObject)
134 {
135 HANDLE FileHandle;
136 PFILE_OBJECT CreatedFileObject;
137
138 DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
139 FileObject, DeviceObject);
140
141 assert_irql(PASSIVE_LEVEL);
142
143 CreatedFileObject = ObCreateObject(&FileHandle,
144 STANDARD_RIGHTS_REQUIRED,
145 NULL,
146 IoFileType);
147 if (CreatedFileObject == NULL)
148 {
149 return(NULL);
150 }
151
152 if (FileObject != NULL)
153 {
154 DeviceObject = FileObject->DeviceObject;
155 }
156 DeviceObject = IoGetAttachedDevice(DeviceObject);
157 CreatedFileObject->DeviceObject = DeviceObject;
158 CreatedFileObject->Vpb = DeviceObject->Vpb;
159 CreatedFileObject->Type = InternalFileType;
160 CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
161
162 ZwClose(FileHandle);
163
164 return(CreatedFileObject);
165 }
166
167 NTSTATUS
168 STDCALL
169 NtCreateFile (
170 PHANDLE FileHandle,
171 ACCESS_MASK DesiredAccess,
172 POBJECT_ATTRIBUTES ObjectAttributes,
173 PIO_STATUS_BLOCK IoStatusBlock,
174 PLARGE_INTEGER AllocateSize,
175 ULONG FileAttributes,
176 ULONG ShareAccess,
177 ULONG CreateDisposition,
178 ULONG CreateOptions,
179 PVOID EaBuffer,
180 ULONG EaLength
181 )
182 /*
183 * FUNCTION: Either causes a new file or directory to be created, or it opens
184 * an existing file, device, directory or volume, giving the caller a handle
185 * for the file object. This handle can be used by subsequent calls to
186 * manipulate data within the file or the file object's state of attributes.
187 * ARGUMENTS:
188 * FileHandle (OUT) = Points to a variable which receives the file
189 * handle on return
190 * DesiredAccess = Desired access to the file
191 * ObjectAttributes = Structure describing the file
192 * IoStatusBlock (OUT) = Receives information about the operation on
193 * return
194 * AllocationSize = Initial size of the file in bytes
195 * FileAttributes = Attributes to create the file with
196 * ShareAccess = Type of shared access the caller would like to the file
197 * CreateDisposition = Specifies what to do, depending on whether the
198 * file already exists
199 * CreateOptions = Options for creating a new file
200 * EaBuffer = Undocumented
201 * EaLength = Undocumented
202 * RETURNS: Status
203 */
204 {
205 PFILE_OBJECT FileObject;
206 NTSTATUS Status;
207 PIRP Irp;
208 KEVENT Event;
209 PIO_STACK_LOCATION StackLoc;
210
211 DPRINT("NtCreateFile(FileHandle %x, DesiredAccess %x, "
212 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
213 FileHandle,DesiredAccess,ObjectAttributes,
214 ObjectAttributes->ObjectName->Buffer);
215
216 assert_irql(PASSIVE_LEVEL);
217
218 *FileHandle=0;
219
220 FileObject = ObCreateObject(FileHandle,
221 DesiredAccess,
222 ObjectAttributes,
223 IoFileType);
224 if (FileObject == NULL)
225 {
226 return(STATUS_UNSUCCESSFUL);
227 }
228
229 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
230 {
231 FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO;
232 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
233 }
234 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
235 {
236 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
237 }
238
239 KeInitializeEvent(&Event, NotificationEvent, FALSE);
240
241 DPRINT("FileObject %x\n", FileObject);
242 DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
243 Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
244 if (Irp==NULL)
245 {
246 return(STATUS_UNSUCCESSFUL);
247 }
248
249 StackLoc = IoGetNextIrpStackLocation(Irp);
250 StackLoc->MajorFunction = IRP_MJ_CREATE;
251 StackLoc->MinorFunction = 0;
252 StackLoc->Flags = 0;
253 StackLoc->Control = 0;
254 StackLoc->DeviceObject = FileObject->DeviceObject;
255 StackLoc->FileObject = FileObject;
256 StackLoc->Parameters.Create.Options = CreateOptions&FILE_VALID_OPTION_FLAGS;
257 StackLoc->Parameters.Create.Options |= CreateDisposition<<24;
258
259 Status = IoCallDriver(FileObject->DeviceObject,Irp);
260 if (Status == STATUS_PENDING)
261 {
262 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
263 Status = IoStatusBlock->Status;
264 }
265
266 if (!NT_SUCCESS(Status))
267 {
268 DPRINT("Failing create request with status %x\n",Status);
269 ZwClose(*FileHandle);
270 (*FileHandle) = 0;
271 }
272
273 assert_irql(PASSIVE_LEVEL);
274 DPRINT("Finished NtCreateFile() (*FileHandle) %x\n",(*FileHandle));
275 return(Status);
276 }
277
278
279 NTSTATUS STDCALL NtOpenFile(PHANDLE FileHandle,
280 ACCESS_MASK DesiredAccess,
281 POBJECT_ATTRIBUTES ObjectAttributes,
282 PIO_STATUS_BLOCK IoStatusBlock,
283 ULONG ShareAccess,
284 ULONG OpenOptions)
285 /*
286 * FUNCTION: Opens a file (simpler than ZwCreateFile)
287 * ARGUMENTS:
288 * FileHandle (OUT) = Variable that receives the file handle on return
289 * DesiredAccess = Access desired by the caller to the file
290 * ObjectAttributes = Structue describing the file to be opened
291 * IoStatusBlock (OUT) = Receives details about the result of the
292 * operation
293 * ShareAccess = Type of shared access the caller requires
294 * OpenOptions = Options for the file open
295 * RETURNS: Status
296 * NOTE: Undocumented
297 */
298 {
299 return(ZwCreateFile(FileHandle,
300 DesiredAccess,
301 ObjectAttributes,
302 IoStatusBlock,
303 NULL,
304 0,
305 ShareAccess,
306 FILE_OPEN,
307 OpenOptions,
308 NULL,
309 0));
310 }
311
312