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