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