*/
/*
* PROJECT: ReactOS kernel
- * FILE: drivers/fs/vfat/create.c
+ * FILE: drivers/filesystems/fastfat/create.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
+ * Pierre Schweitzer (pierre@reactos.org)
*/
/* INCLUDES *****************************************************************/
PUNICODE_STRING PathNameU,
PFILE_OBJECT FileObject,
ULONG RequestedDisposition,
- BOOLEAN OpenTargetDir,
PVFATFCB *ParentFcb)
{
PVFATFCB Fcb;
return Status;
}
- /* In case we're to open target, just check whether file exist, but don't open it */
- if (OpenTargetDir)
- {
- vfatReleaseFCB(DeviceExt, Fcb);
- return STATUS_OBJECT_NAME_COLLISION;
- }
-
if (Fcb->Flags & FCB_DELETE_PENDING)
{
vfatReleaseFCB(DeviceExt, Fcb);
RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
-#if 0
OpenTargetDir = (Stack->Flags & SL_OPEN_TARGET_DIRECTORY) ? TRUE : FALSE;
-#else
- OpenTargetDir = FALSE;
-#endif
+
FileObject = Stack->FileObject;
DeviceExt = DeviceObject->DeviceExtension;
}
/* Try opening the file. */
- Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, OpenTargetDir, &ParentFcb);
-
- if (OpenTargetDir)
+ if (!OpenTargetDir)
{
+ Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, &ParentFcb);
+ }
+ else
+ {
+ PVFATFCB TargetFcb;
LONG idx, FileNameLen;
- if (Status == STATUS_OBJECT_NAME_COLLISION)
+ ParentFcb = (FileObject->RelatedFileObject != NULL) ? FileObject->RelatedFileObject->FsContext : NULL;
+ Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
+
+ if (Status == STATUS_SUCCESS)
{
+ ParentFcb->RefCount++;
+ vfatReleaseFCB(DeviceExt, TargetFcb);
Irp->IoStatus.Information = FILE_EXISTS;
}
else
/* We don't want to include / in the name */
FileNameLen = PathNameU.Length - ((idx + 1) * sizeof(WCHAR));
- /* Try to open parent */
- PathNameU.Length -= (PathNameU.Length - idx * sizeof(WCHAR));
- Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, FALSE, &ParentFcb);
-
/* Update FO just to keep file name */
/* Skip first slash */
++idx;
/* This is a relative open and we have only the filename, so open the parent directory
* It is in RelatedFileObject
*/
- BOOLEAN Chomp = FALSE;
- PFILE_OBJECT RelatedFileObject = FileObject->RelatedFileObject;
+ ASSERT(FileObject->RelatedFileObject != NULL);
- DPRINT("%wZ\n", &PathNameU);
+ /* No need to modify the FO, it already has the name */
+ }
- ASSERT(RelatedFileObject != NULL);
+ /* We're done with opening! */
+ if (ParentFcb != NULL)
+ {
+ Status = vfatAttachFCBToFileObject(DeviceExt, ParentFcb, FileObject);
+ }
- DPRINT("Relative opening\n");
- DPRINT("FileObject->RelatedFileObject->FileName: %wZ\n", &RelatedFileObject->FileName);
+ if (NT_SUCCESS(Status))
+ {
+ pFcb = FileObject->FsContext;
- /* VfatOpenFile() doesn't like our name ends with \, so chomp it if there's one */
- if (RelatedFileObject->FileName.Buffer[RelatedFileObject->FileName.Length / sizeof(WCHAR) - 1] == L'\\')
+ if (pFcb->OpenHandleCount == 0)
{
- Chomp = TRUE;
- RelatedFileObject->FileName.Length -= sizeof(WCHAR);
+ IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Stack->Parameters.Create.ShareAccess,
+ FileObject,
+ &pFcb->FCBShareAccess);
+ }
+ else
+ {
+ Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Stack->Parameters.Create.ShareAccess,
+ FileObject,
+ &pFcb->FCBShareAccess,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ VfatCloseFile(DeviceExt, FileObject);
+ return Status;
+ }
}
- /* Tricky part - fake our FO. It's NOT relative, we want to open the complete file path */
- FileObject->RelatedFileObject = NULL;
- Status = VfatOpenFile(DeviceExt, &RelatedFileObject->FileName, FileObject, RequestedDisposition, FALSE, &ParentFcb);
-
- /* We're done opening, restore what we broke */
- FileObject->RelatedFileObject = RelatedFileObject;
- if (Chomp) RelatedFileObject->FileName.Length += sizeof(WCHAR);
-
- /* No need to modify the FO, it already has the name */
+ pFcb->OpenHandleCount++;
+ }
+ else if (ParentFcb != NULL)
+ {
+ vfatReleaseFCB(DeviceExt, ParentFcb);
}
return Status;
Attributes |= FILE_ATTRIBUTE_ARCHIVE;
vfatSplitPathName(&PathNameU, NULL, &FileNameU);
Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
- (UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
+ (UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS), NULL);
vfatReleaseFCB(DeviceExt, ParentFcb);
if (NT_SUCCESS(Status))
{