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