3 * Copyright (C) 2002, 2003, 2004 ReactOS Team
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.
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.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: drivers/filesystems/cdfs/cdfs.c
23 * PURPOSE: CDROM (ISO 9660) filesystem driver
24 * PROGRAMMER: Art Yerkes
28 /* INCLUDES *****************************************************************/
35 /* FUNCTIONS ****************************************************************/
38 CdfsMakeAbsoluteFilename(PFILE_OBJECT FileObject
,
39 PUNICODE_STRING RelativeFileName
,
40 PUNICODE_STRING AbsoluteFileName
)
46 DPRINT("try related for %wZ\n", RelativeFileName
);
47 Fcb
= FileObject
->FsContext
;
50 /* verify related object is a directory and target name
51 don't start with \. */
52 if ((Fcb
->Entry
.FileFlags
& FILE_FLAG_DIRECTORY
) == 0 ||
53 (RelativeFileName
->Length
>= sizeof(WCHAR
) &&
54 RelativeFileName
->Buffer
[0] == L
'\\'))
56 return STATUS_INVALID_PARAMETER
;
59 /* construct absolute path name */
60 Length
= Fcb
->PathName
.Length
+
62 RelativeFileName
->Length
+
64 AbsoluteFileName
->Length
= 0;
65 AbsoluteFileName
->MaximumLength
= Length
;
66 AbsoluteFileName
->Buffer
= ExAllocatePoolWithTag(NonPagedPool
, Length
, CDFS_FILENAME_TAG
);
67 if (AbsoluteFileName
->Buffer
== NULL
)
69 return STATUS_INSUFFICIENT_RESOURCES
;
72 Status
= RtlAppendUnicodeStringToString(AbsoluteFileName
,
74 if (!NT_SUCCESS(Status
))
76 RtlFreeUnicodeString(AbsoluteFileName
);
80 if (!CdfsFCBIsRoot(Fcb
))
82 Status
= RtlAppendUnicodeToString(AbsoluteFileName
,
84 if (!NT_SUCCESS(Status
))
86 RtlFreeUnicodeString(AbsoluteFileName
);
91 Status
= RtlAppendUnicodeStringToString(AbsoluteFileName
,
93 if (!NT_SUCCESS(Status
))
95 RtlFreeUnicodeString(AbsoluteFileName
);
99 return STATUS_SUCCESS
;
104 * FUNCTION: Opens a file
107 CdfsOpenFile(PDEVICE_EXTENSION DeviceExt
,
108 PFILE_OBJECT FileObject
,
109 PUNICODE_STRING FileName
)
114 UNICODE_STRING AbsFileName
;
116 DPRINT("CdfsOpenFile(%p, %p, %wZ)\n", DeviceExt
, FileObject
, FileName
);
118 if (FileObject
->RelatedFileObject
)
120 DPRINT("Converting relative filename to absolute filename\n");
122 Status
= CdfsMakeAbsoluteFilename(FileObject
->RelatedFileObject
,
125 if (!NT_SUCCESS(Status
))
130 FileName
= &AbsFileName
;
133 Status
= CdfsDeviceIoControl (DeviceExt
->StorageDevice
,
134 IOCTL_CDROM_CHECK_VERIFY
,
140 DPRINT ("Status %lx\n", Status
);
141 if (!NT_SUCCESS(Status
))
143 DPRINT1 ("Status %lx\n", Status
);
147 DPRINT("PathName to open: %wZ\n", FileName
);
149 /* try first to find an existing FCB in memory */
150 DPRINT("Checking for existing FCB in memory\n");
151 Fcb
= CdfsGrabFCBFromTable(DeviceExt
,
155 DPRINT("No existing FCB found, making a new one if file exists.\n");
156 Status
= CdfsGetFCBForFile(DeviceExt
,
160 if (ParentFcb
!= NULL
)
162 CdfsReleaseFCB(DeviceExt
,
166 if (!NT_SUCCESS (Status
))
168 DPRINT("Could not make a new FCB, status: %x\n", Status
);
170 if (FileName
== &AbsFileName
)
171 RtlFreeUnicodeString(&AbsFileName
);
177 DPRINT("Attaching FCB to fileObject\n");
178 Status
= CdfsAttachFCBToFileObject(DeviceExt
,
182 if ((FileName
== &AbsFileName
) && AbsFileName
.Buffer
)
183 ExFreePoolWithTag(AbsFileName
.Buffer
, CDFS_FILENAME_TAG
);
190 * FUNCTION: Opens a file
193 CdfsCreateFile(PDEVICE_OBJECT DeviceObject
,
196 PDEVICE_EXTENSION DeviceExt
;
197 PIO_STACK_LOCATION Stack
;
198 PFILE_OBJECT FileObject
;
199 ULONG RequestedDisposition
;
200 ULONG RequestedOptions
;
204 DPRINT("CdfsCreateFile() called\n");
206 DeviceExt
= DeviceObject
->DeviceExtension
;
208 Stack
= IoGetCurrentIrpStackLocation (Irp
);
211 RequestedDisposition
= ((Stack
->Parameters
.Create
.Options
>> 24) & 0xff);
212 RequestedOptions
= Stack
->Parameters
.Create
.Options
& FILE_VALID_OPTION_FLAGS
;
213 DPRINT("RequestedDisposition %x, RequestedOptions %x\n",
214 RequestedDisposition
, RequestedOptions
);
216 FileObject
= Stack
->FileObject
;
218 if (RequestedDisposition
== FILE_CREATE
||
219 RequestedDisposition
== FILE_OVERWRITE_IF
||
220 RequestedDisposition
== FILE_SUPERSEDE
)
222 return STATUS_ACCESS_DENIED
;
225 Status
= CdfsOpenFile(DeviceExt
,
227 &FileObject
->FileName
);
228 if (NT_SUCCESS(Status
))
230 Fcb
= FileObject
->FsContext
;
232 /* Check whether the file has the requested attributes */
233 if (RequestedOptions
& FILE_NON_DIRECTORY_FILE
&& CdfsFCBIsDirectory(Fcb
))
235 CdfsCloseFile (DeviceExt
, FileObject
);
236 return STATUS_FILE_IS_A_DIRECTORY
;
239 if (RequestedOptions
& FILE_DIRECTORY_FILE
&& !CdfsFCBIsDirectory(Fcb
))
241 CdfsCloseFile (DeviceExt
, FileObject
);
242 return STATUS_NOT_A_DIRECTORY
;
247 * If the directory containing the file to open doesn't exist then
250 Irp
->IoStatus
.Information
= (NT_SUCCESS(Status
)) ? FILE_OPENED
: 0;
258 PCDFS_IRP_CONTEXT IrpContext
)
260 PDEVICE_OBJECT DeviceObject
;
261 PDEVICE_EXTENSION DeviceExt
;
264 DPRINT("CdfsCreate()\n");
268 DeviceObject
= IrpContext
->DeviceObject
;
269 if (DeviceObject
== CdfsGlobalData
->DeviceObject
)
271 /* DeviceObject represents FileSystem instead of logical volume */
272 DPRINT("Opening file system\n");
273 IrpContext
->Irp
->IoStatus
.Information
= FILE_OPENED
;
274 return STATUS_SUCCESS
;
277 DeviceExt
= DeviceObject
->DeviceExtension
;
279 KeEnterCriticalRegion();
280 ExAcquireResourceExclusiveLite(&DeviceExt
->DirResource
,
282 Status
= CdfsCreateFile(DeviceObject
,
284 ExReleaseResourceLite(&DeviceExt
->DirResource
);
285 KeLeaveCriticalRegion();