49810da58116b1bb8fb01303fb653567d9e62e8e
[reactos.git] / reactos / drivers / fs / cdfs / create.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: create.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/fs/cdfs/cdfs.c
24 * PURPOSE: CDROM (ISO 9660) filesystem driver
25 * PROGRAMMER: Art Yerkes
26 * UPDATE HISTORY:
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include <ddk/ntddk.h>
32
33 //#define NDEBUG
34 #include <debug.h>
35
36 #include "cdfs.h"
37
38
39 /* FUNCTIONS ****************************************************************/
40
41 #if 0
42 NTSTATUS
43 vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject,
44 PWSTR pRelativeFileName,
45 PWSTR *pAbsoluteFilename)
46 {
47 PWSTR rcName;
48 PVFATFCB fcb;
49 PVFATCCB ccb;
50
51 DPRINT ("try related for %S\n", pRelativeFileName);
52 ccb = pFileObject->FsContext2;
53 assert (ccb);
54 fcb = ccb->pFcb;
55 assert (fcb);
56
57 /* verify related object is a directory and target name
58 don't start with \. */
59 if (!(fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
60 || (pRelativeFileName[0] == L'\\'))
61 {
62 return STATUS_INVALID_PARAMETER;
63 }
64
65 /* construct absolute path name */
66 assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
67 <= MAX_PATH);
68 rcName = ExAllocatePool (NonPagedPool, MAX_PATH * sizeof(WCHAR));
69 if (!rcName)
70 {
71 return STATUS_INSUFFICIENT_RESOURCES;
72 }
73 wcscpy (rcName, fcb->PathName);
74 if (!vfatFCBIsRoot(fcb))
75 wcscat (rcName, L"\\");
76 wcscat (rcName, pRelativeFileName);
77 *pAbsoluteFilename = rcName;
78
79 return STATUS_SUCCESS;
80 }
81 #endif
82
83
84 static NTSTATUS
85 CdfsOpenFile(PDEVICE_EXTENSION DeviceExt,
86 PFILE_OBJECT FileObject,
87 PWSTR FileName)
88 /*
89 * FUNCTION: Opens a file
90 */
91 {
92 PFCB ParentFcb;
93 PFCB Fcb;
94 NTSTATUS Status;
95 PWSTR AbsFileName = NULL;
96
97 DPRINT("CdfsOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
98
99 if (FileObject->RelatedFileObject)
100 {
101 DPRINT("Converting relative filename to absolute filename\n");
102 #if 0
103 Status = vfatMakeAbsoluteFilename(FileObject->RelatedFileObject,
104 FileName,
105 &AbsFileName);
106 FileName = AbsFileName;
107 if (!NT_SUCCESS(Status))
108 {
109 return(Status);
110 }
111 #endif
112 return(STATUS_UNSUCCESSFUL);
113 }
114
115 //FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
116
117 DPRINT("PathName to open: %S\n", FileName);
118
119 /* try first to find an existing FCB in memory */
120 DPRINT("Checking for existing FCB in memory\n");
121 Fcb = CdfsGrabFCBFromTable(DeviceExt,
122 FileName);
123 if (Fcb == NULL)
124 {
125 DPRINT ("No existing FCB found, making a new one if file exists.\n");
126 Status = CdfsGetFCBForFile(DeviceExt,
127 &ParentFcb,
128 &Fcb,
129 FileName);
130 if (ParentFcb != NULL)
131 {
132 CdfsReleaseFCB(DeviceExt,
133 ParentFcb);
134 }
135
136 if (!NT_SUCCESS (Status))
137 {
138 DPRINT("Could not make a new FCB, status: %x\n", Status);
139
140 if (AbsFileName)
141 ExFreePool(AbsFileName);
142
143 return(Status);
144 }
145 }
146
147 DPRINT("Attaching FCB to fileObject\n");
148 Status = CdfsAttachFCBToFileObject(DeviceExt,
149 Fcb,
150 FileObject);
151
152 if (AbsFileName)
153 ExFreePool (AbsFileName);
154
155 return Status;
156 }
157
158
159
160
161 static NTSTATUS
162 CdfsCreateFile(PDEVICE_OBJECT DeviceObject,
163 PIRP Irp)
164 /*
165 * FUNCTION: Opens a file
166 */
167 {
168 PDEVICE_EXTENSION DeviceExt;
169 PIO_STACK_LOCATION Stack;
170 PFILE_OBJECT FileObject;
171 ULONG RequestedDisposition;
172 ULONG RequestedOptions;
173 PFCB Fcb;
174 // PWSTR FileName;
175 NTSTATUS Status;
176
177 DPRINT1("CdfsCreateFile() called\n");
178
179 DeviceExt = DeviceObject->DeviceExtension;
180 assert (DeviceExt);
181 Stack = IoGetCurrentIrpStackLocation (Irp);
182 assert (Stack);
183
184 RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
185 // RequestedOptions =
186 // Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
187 // PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
188 // if ((RequestedOptions & FILE_DIRECTORY_FILE)
189 // && RequestedDisposition == FILE_SUPERSEDE)
190 // return STATUS_INVALID_PARAMETER;
191
192 FileObject = Stack->FileObject;
193
194 Status = CdfsOpenFile(DeviceExt,
195 FileObject,
196 FileObject->FileName.Buffer);
197
198 /*
199 * If the directory containing the file to open doesn't exist then
200 * fail immediately
201 */
202 Irp->IoStatus.Information = 0;
203 Irp->IoStatus.Status = Status;
204 return(Status);
205
206 #if 0
207 /* Just skip leading backslashes... */
208 while (*FileName == L'\\')
209 FileName++;
210 CHECKPOINT1;
211
212 Fcb = FsdSearchDirectory(DeviceExt->fss,
213 NULL,
214 FileName);
215 CHECKPOINT1;
216 if (Fcb == NULL)
217 {
218 DPRINT1("FsdSearchDirectory() failed\n");
219 return(STATUS_OBJECT_PATH_NOT_FOUND);
220 }
221 CHECKPOINT1;
222
223 FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID |
224 FO_DIRECT_CACHE_PAGING_READ;
225 FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
226 FileObject->FsContext = Fcb;
227 FileObject->FsContext2 = DeviceExt->fss;
228
229 DPRINT1("FsdOpenFile() done\n");
230
231 return(STATUS_SUCCESS);
232 #endif
233 }
234
235
236 NTSTATUS STDCALL
237 CdfsCreate(PDEVICE_OBJECT DeviceObject,
238 PIRP Irp)
239 {
240 PDEVICE_EXTENSION DeviceExt;
241 NTSTATUS Status;
242
243 if (DeviceObject->Size == sizeof(DEVICE_OBJECT))
244 {
245 /* DeviceObject represents FileSystem instead of logical volume */
246 DPRINT("FsdCreate called with file system\n");
247 Irp->IoStatus.Information = FILE_OPENED;
248 Status = STATUS_SUCCESS;
249 goto ByeBye;
250 }
251
252 DeviceExt = DeviceObject->DeviceExtension;
253
254 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
255 TRUE);
256 Status = CdfsCreateFile(DeviceObject,
257 Irp);
258 ExReleaseResourceLite(&DeviceExt->DirResource);
259
260
261 ByeBye:
262 Irp->IoStatus.Status = Status;
263 IoCompleteRequest(Irp,
264 NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
265
266 return(Status);
267 }
268
269 /* EOF */