Corrected a memory leak in the read cleanup code
[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@mcmail.com)
7 * UPDATE HISTORY:
8 * 24/05/98: Created
9 */
10
11 /* INCLUDES ***************************************************************/
12
13 #include <windows.h>
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/io.h>
17 #include <internal/string.h>
18 #include <wstring.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 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 ZwCreateFile(PHANDLE FileHandle,
61 ACCESS_MASK DesiredAccess,
62 POBJECT_ATTRIBUTES ObjectAttributes,
63 PIO_STATUS_BLOCK IoStatusBlock,
64 PLARGE_INTEGER AllocateSize,
65 ULONG FileAttributes,
66 ULONG ShareAccess,
67 ULONG CreateDisposition,
68 ULONG CreateOptions,
69 PVOID EaBuffer,
70 ULONG EaLength)
71 /*
72 * FUNCTION: Either causes a new file or directory to be created, or it opens
73 * an existing file, device, directory or volume, giving the caller a handle
74 * for the file object. This handle can be used by subsequent calls to
75 * manipulate data within the file or the file object's state of attributes.
76 * ARGUMENTS:
77 * FileHandle (OUT) = Points to a variable which receives the file
78 * handle on return
79 * DesiredAccess = Desired access to the file
80 * ObjectAttributes = Structure describing the file
81 * IoStatusBlock (OUT) = Receives information about the operation on
82 * return
83 * AllocationSize = Initial size of the file in bytes
84 * FileAttributes = Attributes to create the file with
85 * ShareAccess = Type of shared access the caller would like to the file
86 * CreateDisposition = Specifies what to do, depending on whether the
87 * file already exists
88 * CreateOptions = Options for creating a new file
89 * EaBuffer = Undocumented
90 * EaLength = Undocumented
91 * RETURNS: Status
92 */
93 {
94 PVOID Object;
95 NTSTATUS Status;
96 PIRP Irp;
97 KEVENT Event;
98 PDEVICE_OBJECT DeviceObject;
99 PFILE_OBJECT FileObject;
100 PIO_STACK_LOCATION StackLoc;
101 PWSTR Remainder;
102
103 DPRINT("ZwCreateFile(FileHandle %x, DesiredAccess %x, "
104 "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %w)\n",
105 FileHandle,DesiredAccess,ObjectAttributes,
106 ObjectAttributes->ObjectName->Buffer);
107
108 assert_irql(PASSIVE_LEVEL);
109
110 *FileHandle=0;
111
112 FileObject = ObGenericCreateObject(FileHandle,DesiredAccess,NULL,IoFileType);
113 memset(FileObject,0,sizeof(FILE_OBJECT));
114
115 Status = ObOpenObjectByName(ObjectAttributes,&Object,&Remainder);
116
117 if (Status != STATUS_SUCCESS && Status != STATUS_FS_QUERY_REQUIRED)
118 {
119 DPRINT("%s() = Failed to find object\n",__FUNCTION__);
120 ZwClose(*FileHandle);
121 *FileHandle=0;
122 return(STATUS_UNSUCCESSFUL);
123 }
124
125
126 DeviceObject = (PDEVICE_OBJECT)Object;
127 DeviceObject = IoGetAttachedDevice(DeviceObject);
128 DPRINT("DeviceObject %x\n",DeviceObject);
129
130 if (Status == STATUS_SUCCESS)
131 {
132 CHECKPOINT;
133 FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
134 FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
135 ObjectAttributes->ObjectName->Length);
136 FileObject->FileName.Length = ObjectAttributes->Length;
137 RtlCopyUnicodeString(&(FileObject->FileName),
138 ObjectAttributes->ObjectName);
139 }
140 else
141 {
142 CHECKPOINT;
143 if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM &&
144 DeviceObject->DeviceType != FILE_DEVICE_DISK)
145 {
146 ZwClose(*FileHandle);
147 *FileHandle=0;
148 return(STATUS_UNSUCCESSFUL);
149 }
150 if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
151 {
152 Status = IoTryToMountStorageDevice(DeviceObject);
153 if (Status!=STATUS_SUCCESS)
154 {
155 ZwClose(*FileHandle);
156 *FileHandle=0;
157 return(Status);
158 }
159 DeviceObject = IoGetAttachedDevice(DeviceObject);
160 }
161 DPRINT("Remainder %w\n",Remainder);
162 FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
163 wstrlen(Remainder));
164 RtlInitUnicodeString(&(FileObject->FileName),Remainder);
165 DPRINT("FileObject->FileName.Buffer %x %w\n",
166 FileObject->FileName.Buffer,FileObject->FileName.Buffer);
167 }
168 CHECKPOINT;
169
170 if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
171 {
172 FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO;
173 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
174 }
175 if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
176 {
177 FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO;
178 }
179
180 FileObject->DeviceObject=DeviceObject;
181 FileObject->Vpb=DeviceObject->Vpb;
182
183 KeInitializeEvent(&Event,NotificationEvent,FALSE);
184
185 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
186 if (Irp==NULL)
187 {
188 ZwClose(*FileHandle);
189 *FileHandle=0;
190 return(STATUS_UNSUCCESSFUL);
191 }
192
193 StackLoc = IoGetNextIrpStackLocation(Irp);
194 StackLoc->MajorFunction = IRP_MJ_CREATE;
195 StackLoc->MinorFunction = 0;
196 StackLoc->Flags = 0;
197 StackLoc->Control = 0;
198 StackLoc->DeviceObject = DeviceObject;
199 StackLoc->FileObject=FileObject;
200 Status = IoCallDriver(DeviceObject,Irp);
201 if (Status==STATUS_PENDING)
202 {
203 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
204 Status = IoStatusBlock->Status;
205 }
206
207 if (Status!=STATUS_SUCCESS)
208 {
209 ZwClose(*FileHandle);
210 *FileHandle=0;
211 }
212
213 DPRINT("*FileHandle %x\n",*FileHandle);
214
215 return(Status);
216
217 }
218
219 NTSTATUS NtOpenFile(PHANDLE FileHandle,
220 ACCESS_MASK DesiredAccess,
221 POBJECT_ATTRIBUTES ObjectAttributes,
222 PIO_STATUS_BLOCK IoStatusBlock,
223 ULONG ShareAccess,
224 ULONG OpenOptions)
225 {
226 return(ZwOpenFile(FileHandle,
227 DesiredAccess,
228 ObjectAttributes,
229 IoStatusBlock,
230 ShareAccess,
231 OpenOptions));
232 }
233
234 NTSTATUS ZwOpenFile(PHANDLE FileHandle,
235 ACCESS_MASK DesiredAccess,
236 POBJECT_ATTRIBUTES ObjectAttributes,
237 PIO_STATUS_BLOCK IoStatusBlock,
238 ULONG ShareAccess,
239 ULONG OpenOptions)
240 /*
241 * FUNCTION: Opens a file (simpler than ZwCreateFile)
242 * ARGUMENTS:
243 * FileHandle (OUT) = Variable that receives the file handle on return
244 * DesiredAccess = Access desired by the caller to the file
245 * ObjectAttributes = Structue describing the file to be opened
246 * IoStatusBlock (OUT) = Receives details about the result of the
247 * operation
248 * ShareAccess = Type of shared access the caller requires
249 * OpenOptions = Options for the file open
250 * RETURNS: Status
251 * NOTE: Undocumented
252 */
253 {
254 return(ZwCreateFile(FileHandle,
255 DesiredAccess,
256 ObjectAttributes,
257 IoStatusBlock,
258 NULL,
259 0,
260 ShareAccess,
261 FILE_OPEN,
262 OpenOptions,
263 NULL,
264 0));
265 }
266
267