* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: create.c,v 1.64 2003/10/11 17:51:56 hbirr Exp $
- *
+/*
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/create.c
* PURPOSE: VFAT Filesystem
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <wchar.h>
-#include <limits.h>
-
#define NDEBUG
-#include <debug.h>
-
#include "vfat.h"
-/* GLOBALS *******************************************************************/
-
-#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
-
/* FUNCTIONS *****************************************************************/
void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
{
OEM_STRING StringA;
- ULONG Length;
+ USHORT Length;
CHAR cString[12];
-
- memcpy(cString, pEntry->Filename, 11);
+
+ RtlCopyMemory(cString, pEntry->ShortName, 11);
cString[11] = 0;
if (cString[0] == 0x05)
{
cString[0] = 0xe5;
- }
+ }
StringA.Buffer = cString;
- for (StringA.Length = 0;
+ for (StringA.Length = 0;
StringA.Length < 8 && StringA.Buffer[StringA.Length] != ' ';
StringA.Length++);
StringA.MaximumLength = StringA.Length;
-
+
RtlOemStringToUnicodeString(NameU, &StringA, FALSE);
if (pEntry->lCase & VFAT_CASE_LOWER_BASE)
{
Length = NameU->Length;
NameU->Buffer += Length / sizeof(WCHAR);
- if (!ENTRY_VOLUME(pEntry))
+ if (!FAT_ENTRY_VOLUME(pEntry))
{
Length += sizeof(WCHAR);
NameU->Buffer[0] = L'.';
}
NameU->Length = 0;
NameU->MaximumLength -= Length;
-
+
StringA.Buffer = &cString[8];
- for (StringA.Length = 0;
+ for (StringA.Length = 0;
StringA.Length < 3 && StringA.Buffer[StringA.Length] != ' ';
StringA.Length++);
StringA.MaximumLength = StringA.Length;
{
PVOID Context = NULL;
ULONG DirIndex = 0;
- FATDirEntry* Entry;
+ PDIR_ENTRY Entry;
PVFATFCB pFcb;
LARGE_INTEGER FileOffset;
UNICODE_STRING NameU;
+ ULONG SizeDirEntry;
+ ULONG EntriesPerPage;
+ OEM_STRING StringO;
NameU.Buffer = Vpb->VolumeLabel;
NameU.Length = 0;
*(Vpb->VolumeLabel) = 0;
Vpb->VolumeLabelLength = 0;
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ SizeDirEntry = sizeof(FATX_DIR_ENTRY);
+ EntriesPerPage = FATX_ENTRIES_PER_PAGE;
+ }
+ else
+ {
+ SizeDirEntry = sizeof(FAT_DIR_ENTRY);
+ EntriesPerPage = FAT_ENTRIES_PER_PAGE;
+ }
+
ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
pFcb = vfatOpenRootFCB (DeviceExt);
ExReleaseResourceLite (&DeviceExt->DirResource);
{
while (TRUE)
{
- if (ENTRY_VOLUME(Entry))
+ if (ENTRY_VOLUME(DeviceExt, Entry))
{
/* copy volume label */
- vfat8Dot3ToString (Entry, &NameU);
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ StringO.Buffer = (PCHAR)Entry->FatX.Filename;
+ StringO.MaximumLength = StringO.Length = Entry->FatX.FilenameLength;
+ RtlOemStringToUnicodeString(&NameU, &StringO, FALSE);
+ }
+ else
+ {
+ vfat8Dot3ToString (&Entry->Fat, &NameU);
+ }
Vpb->VolumeLabelLength = NameU.Length;
break;
}
- if (ENTRY_END(Entry))
+ if (ENTRY_END(DeviceExt, Entry))
{
break;
}
- DirIndex++;
- Entry++;
- if ((DirIndex % ENTRIES_PER_PAGE) == 0)
+ DirIndex++;
+ Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
+ if ((DirIndex % EntriesPerPage) == 0)
{
CcUnpinData(Context);
FileOffset.u.LowPart += PAGE_SIZE;
* FUNCTION: Find a file
*/
{
- WCHAR PathNameBuffer[MAX_PATH];
+ PWCHAR PathNameBuffer;
+ USHORT PathNameBufferLength;
NTSTATUS Status;
PVOID Context = NULL;
PVOID Page;
PVFATFCB rcFcb;
- BOOLEAN FoundLong;
- BOOLEAN FoundShort;
+ BOOLEAN Found;
UNICODE_STRING PathNameU;
+ UNICODE_STRING FileToFindUpcase;
BOOLEAN WildCard;
- PWCHAR curr, last;
- DPRINT ("FindFile(Parent %x, FileToFind '%wZ', DirIndex: %d)\n",
+ DPRINT ("FindFile(Parent %x, FileToFind '%wZ', DirIndex: %d)\n",
Parent, FileToFindU, DirContext->DirIndex);
DPRINT ("FindFile: Path %wZ)\n",&Parent->PathNameU);
+ PathNameBufferLength = LONGNAME_MAX_LENGTH * sizeof(WCHAR);
+ PathNameBuffer = ExAllocatePool(NonPagedPool, PathNameBufferLength + sizeof(WCHAR));
+ if (!PathNameBuffer)
+ {
+ CHECKPOINT1;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
PathNameU.Buffer = PathNameBuffer;
PathNameU.Length = 0;
- PathNameU.MaximumLength = sizeof(PathNameBuffer);
+ PathNameU.MaximumLength = PathNameBufferLength;
DirContext->LongNameU.Length = 0;
DirContext->ShortNameU.Length = 0;
- /* FIXME: Use FsRtlDoesNameContainWildCards */
- WildCard = FALSE;
- curr = FileToFindU->Buffer;
- last = FileToFindU->Buffer + FileToFindU->Length / sizeof(WCHAR);
- while (curr < last)
- {
- if (*curr == L'?' || *curr == L'*')
- {
- WildCard = TRUE;
- break;
- }
- curr++;
- }
+ WildCard = FsRtlDoesNameContainWildCards(FileToFindU);
if (WildCard == FALSE)
{
rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
if (rcFcb)
{
- if(rcFcb->startIndex >= DirContext->DirIndex)
+ ULONG startIndex = rcFcb->startIndex;
+ if ((rcFcb->Flags & FCB_IS_FATX_ENTRY) && !vfatFCBIsRoot(Parent))
+ {
+ startIndex += 2;
+ }
+ if(startIndex >= DirContext->DirIndex)
{
RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
- memcpy(&DirContext->FatDirEntry, &rcFcb->entry, sizeof(FATDirEntry));
+ RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
DirContext->StartIndex = rcFcb->startIndex;
DirContext->DirIndex = rcFcb->dirIndex;
DPRINT("FindFile: new Name %wZ, DirIndex %d (%d)\n",
- &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
+ &DirContext->LongNameU, DirContext->DirIndex, DirContext->StartIndex);
Status = STATUS_SUCCESS;
}
else
Status = STATUS_UNSUCCESSFUL;
}
vfatReleaseFCB(DeviceExt, rcFcb);
+ ExFreePool(PathNameBuffer);
return Status;
}
}
+ /* FsRtlIsNameInExpression need the searched string to be upcase,
+ * even if IgnoreCase is specified */
+ Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFindU, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ CHECKPOINT;
+ ExFreePool(PathNameBuffer);
+ return Status;
+ }
+
while(TRUE)
{
- Status = vfatGetNextDirEntry(&Context, &Page, Parent, DirContext, First);
+ Status = DeviceExt->GetNextDirEntry(&Context, &Page, Parent, DirContext, First);
First = FALSE;
if (Status == STATUS_NO_MORE_ENTRIES)
{
break;
}
- if (ENTRY_VOLUME(&DirContext->FatDirEntry))
+ if (ENTRY_VOLUME(DeviceExt, &DirContext->DirEntry))
{
DirContext->DirIndex++;
continue;
}
- DirContext->LongNameU.Buffer[DirContext->LongNameU.Length / sizeof(WCHAR)] = 0;
- DirContext->ShortNameU.Buffer[DirContext->ShortNameU.Length / sizeof(WCHAR)] = 0;
if (WildCard)
{
- /* FIXME: Use FsRtlIsNameInExpression */
- if (DirContext->LongNameU.Length > 0 &&
- wstrcmpjoki (DirContext->LongNameU.Buffer, FileToFindU->Buffer))
- {
- FoundLong = TRUE;
- }
- else
- {
- FoundLong = FALSE;
- }
- if (FoundLong == FALSE)
- {
- /* FIXME: Use FsRtlIsNameInExpression */
- FoundShort = wstrcmpjoki (DirContext->ShortNameU.Buffer, FileToFindU->Buffer);
- }
- else
- {
- FoundShort = FALSE;
- }
+ Found = FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->LongNameU, TRUE, NULL) ||
+ FsRtlIsNameInExpression(&FileToFindUpcase, &DirContext->ShortNameU, TRUE, NULL);
}
else
{
- FoundLong = RtlEqualUnicodeString(&DirContext->LongNameU, FileToFindU, TRUE);
- if (FoundLong == FALSE)
- {
- FoundShort = RtlEqualUnicodeString(&DirContext->ShortNameU, FileToFindU, TRUE);
- }
+ Found = FsRtlAreNamesEqual(&DirContext->LongNameU, FileToFindU, TRUE, NULL) ||
+ FsRtlAreNamesEqual(&DirContext->ShortNameU, FileToFindU, TRUE, NULL);
}
- if (FoundLong || FoundShort)
+ if (Found)
{
if (WildCard)
{
rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
if (rcFcb != NULL)
{
- memcpy(&DirContext->FatDirEntry, &rcFcb->entry, sizeof(FATDirEntry));
+ RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
vfatReleaseFCB(DeviceExt, rcFcb);
}
}
{
CcUnpinData(Context);
}
+ RtlFreeUnicodeString(&FileToFindUpcase);
+ ExFreePool(PathNameBuffer);
return STATUS_SUCCESS;
}
DirContext->DirIndex++;
CcUnpinData(Context);
}
+ RtlFreeUnicodeString(&FileToFindUpcase);
+ ExFreePool(PathNameBuffer);
return Status;
}
NTSTATUS
-VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PUNICODE_STRING FileNameU)
+VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PVFATFCB* ParentFcb)
/*
* FUNCTION: Opens a file
*/
{
- PVFATFCB ParentFcb;
PVFATFCB Fcb;
NTSTATUS Status;
- UNICODE_STRING NameU;
- WCHAR Name[MAX_PATH];
+ UNICODE_STRING PathNameU;
+ WCHAR Buffer[260];
- DPRINT ("VfatOpenFile(%08lx, %08lx, '%wZ')\n", DeviceExt, FileObject, FileNameU);
+ DPRINT ("VfatOpenFile(%08lx, %08lx, '%wZ')\n", DeviceExt, FileObject, &FileObject->FileName);
if (FileObject->RelatedFileObject)
{
- DPRINT ("Converting relative filename to absolute filename\n");
+ DPRINT ("'%wZ'\n", &FileObject->RelatedFileObject->FileName);
- NameU.Buffer = Name;
- NameU.Length = 0;
- NameU.MaximumLength = sizeof(Name);
+ *ParentFcb = FileObject->RelatedFileObject->FsContext;
+ (*ParentFcb)->RefCount++;
+ }
+ else
+ {
+ *ParentFcb = NULL;
+ }
+
+ if (!DeviceExt->FatInfo.FixedMedia)
+ {
+ Status = VfatBlockDeviceIoControl (DeviceExt->StorageDevice,
+ IOCTL_DISK_CHECK_VERIFY,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ FALSE);
+
+ if (Status == STATUS_VERIFY_REQUIRED)
- Fcb = FileObject->RelatedFileObject->FsContext;
- RtlCopyUnicodeString(&NameU, &Fcb->PathNameU);
- if (!vfatFCBIsRoot(Fcb))
{
- NameU.Buffer[NameU.Length / sizeof(WCHAR)] = L'\\';
- NameU.Length += sizeof(WCHAR);
+ PDEVICE_OBJECT DeviceToVerify;
+
+ DPRINT ("Media change detected!\n");
+ DPRINT ("Device %p\n", DeviceExt->StorageDevice);
+
+ DeviceToVerify = IoGetDeviceToVerify (PsGetCurrentThread ());
+
+ IoSetDeviceToVerify (PsGetCurrentThread (),
+ NULL);
+ Status = IoVerifyVolume (DeviceExt->StorageDevice,
+ FALSE);
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT ("Status %lx\n", Status);
+ *ParentFcb = NULL;
+ return Status;
}
- RtlAppendUnicodeStringToString(&NameU, FileNameU);
- NameU.Buffer[NameU.Length / sizeof(WCHAR)] = 0;
- FileNameU = &NameU;
}
- DPRINT ("PathName to open: '%wZ'\n", FileNameU);
+ if (*ParentFcb)
+ {
+ (*ParentFcb)->RefCount++;
+ }
- /* try first to find an existing FCB in memory */
- DPRINT ("Checking for existing FCB in memory\n");
- Fcb = vfatGrabFCBFromTable (DeviceExt, FileNameU);
- if (Fcb == NULL)
+ PathNameU.Buffer = Buffer;
+ PathNameU.Length = 0;
+ PathNameU.MaximumLength = sizeof(Buffer);
+ RtlCopyUnicodeString(&PathNameU, &FileObject->FileName);
+ if (PathNameU.Length > sizeof(WCHAR) &&
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR) - 1] == L'\\')
{
- DPRINT ("No existing FCB found, making a new one if file exists.\n");
- Status = vfatGetFCBForFile (DeviceExt, &ParentFcb, &Fcb, FileNameU);
- if (ParentFcb != NULL)
- {
- vfatReleaseFCB (DeviceExt, ParentFcb);
- }
- if (!NT_SUCCESS (Status))
- {
- DPRINT ("Could not make a new FCB, status: %x\n", Status);
- return Status;
- }
+ PathNameU.Length -= sizeof(WCHAR);
}
+ PathNameU.Buffer[PathNameU.Length / sizeof(WCHAR)] = 0;
+
+ /* try first to find an existing FCB in memory */
+ DPRINT ("Checking for existing FCB in memory\n");
+
+ Status = vfatGetFCBForFile (DeviceExt, ParentFcb, &Fcb, &PathNameU);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("Could not make a new FCB, status: %x\n", Status);
+ return Status;
+ }
if (Fcb->Flags & FCB_DELETE_PENDING)
- {
- vfatReleaseFCB (DeviceExt, Fcb);
- return STATUS_DELETE_PENDING;
- }
+ {
+ vfatReleaseFCB (DeviceExt, Fcb);
+ return STATUS_DELETE_PENDING;
+ }
DPRINT ("Attaching FCB to fileObject\n");
Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
-
+ if (!NT_SUCCESS(Status))
+ {
+ vfatReleaseFCB (DeviceExt, Fcb);
+ }
return Status;
}
-VOID STATIC
-VfatSupersedeFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PVFATFCB Fcb)
-{
- ULONG Cluster, NextCluster;
- NTSTATUS Status;
-
- Fcb->entry.FileSize = 0;
- if (DeviceExt->FatInfo.FatType == FAT32)
- {
- Cluster = Fcb->entry.FirstCluster + Fcb->entry.FirstClusterHigh * 65536;
- }
- else
- {
- Cluster = Fcb->entry.FirstCluster;
- }
- Fcb->entry.FirstCluster = 0;
- Fcb->entry.FirstClusterHigh = 0;
- VfatUpdateEntry (Fcb);
- if (Fcb->RFCB.FileSize.QuadPart > 0)
- {
- Fcb->RFCB.AllocationSize.QuadPart = 0;
- Fcb->RFCB.FileSize.QuadPart = 0;
- Fcb->RFCB.ValidDataLength.QuadPart = 0;
- /* Notify cache manager about the change in file size if caching is
- initialized on the file stream */
- if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
- {
- CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
- }
- }
- while (Cluster != 0xffffffff && Cluster > 1)
- {
- Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE);
- WriteCluster (DeviceExt, Cluster, 0);
- Cluster = NextCluster;
- }
-}
-
NTSTATUS
VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
ULONG RequestedDisposition, RequestedOptions;
PVFATCCB pCcb;
PVFATFCB pFcb;
- PWCHAR c;
+ PVFATFCB ParentFcb;
+ PWCHAR c, last;
BOOLEAN PagingFileCreate = FALSE;
LARGE_INTEGER AllocationSize;
-
+ BOOLEAN Dots;
+ UNICODE_STRING FileNameU;
+
/* Unpack the various parameters. */
Stack = IoGetCurrentIrpStackLocation (Irp);
RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
}
/* This a open operation for the volume itself */
- if (FileObject->FileName.Length == 0 &&
+ if (FileObject->FileName.Length == 0 &&
FileObject->RelatedFileObject == NULL)
- {
+ {
if (RequestedDisposition == FILE_CREATE ||
RequestedDisposition == FILE_OVERWRITE_IF ||
RequestedDisposition == FILE_SUPERSEDE)
{
return (STATUS_INSUFFICIENT_RESOURCES);
}
- memset(pCcb, 0, sizeof(VFATCCB));
- FileObject->Flags |= FO_FCB_IS_VALID;
+ RtlZeroMemory(pCcb, sizeof(VFATCCB));
FileObject->SectionObjectPointer = &pFcb->SectionObjectPointers;
FileObject->FsContext = pFcb;
FileObject->FsContext2 = pCcb;
}
/*
- * Check for illegal characters in the file name
+ * Check for illegal characters and illegale dot sequences in the file name
*/
c = FileObject->FileName.Buffer + FileObject->FileName.Length / sizeof(WCHAR);
+ last = c - 1;
+ Dots = TRUE;
while (c-- > FileObject->FileName.Buffer)
{
+ if (*c == L'\\' || c == FileObject->FileName.Buffer)
+ {
+ if (Dots && last > c)
+ {
+ return(STATUS_OBJECT_NAME_INVALID);
+ }
+ last = c - 1;
+ Dots = TRUE;
+ }
+ else if (*c != L'.')
+ {
+ Dots = FALSE;
+ }
+
if (*c != '\\' && vfatIsLongIllegal(*c))
{
return(STATUS_OBJECT_NAME_INVALID);
}
/* Try opening the file. */
- Status = VfatOpenFile (DeviceExt, FileObject, &FileObject->FileName);
+ Status = VfatOpenFile (DeviceExt, FileObject, &ParentFcb);
/*
* If the directory containing the file to open doesn't exist then
Status == STATUS_INVALID_PARAMETER ||
Status == STATUS_DELETE_PENDING)
{
+ if (ParentFcb)
+ {
+ vfatReleaseFCB (DeviceExt, ParentFcb);
+ }
return(Status);
}
{
ULONG Attributes;
Attributes = Stack->Parameters.Create.FileAttributes;
- Status = VfatAddEntry (DeviceExt, &FileObject->FileName, FileObject, RequestedOptions,
+
+ vfatSplitPathName(&FileObject->FileName, NULL, &FileNameU);
+ Status = VfatAddEntry (DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
(UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
+ vfatReleaseFCB (DeviceExt, ParentFcb);
if (NT_SUCCESS (Status))
{
- pFcb = FileObject->FsContext;
+ Status = vfatAttachFCBToFileObject (DeviceExt, pFcb, FileObject);
+ if ( !NT_SUCCESS(Status) )
+ {
+ vfatReleaseFCB (DeviceExt, pFcb);
+ return Status;
+ }
+
Irp->IoStatus.Information = FILE_CREATED;
- VfatSetAllocationSizeInformation(FileObject,
+
+ VfatSetAllocationSizeInformation(FileObject,
pFcb,
DeviceExt,
&Irp->Overlay.AllocationSize);
- VfatSetExtendedAttributes(FileObject,
+ VfatSetExtendedAttributes(FileObject,
Irp->AssociatedIrp.SystemBuffer,
Stack->Parameters.Create.EaLength);
- IoSetShareAccess(0 /*DesiredAccess*/,
- Stack->Parameters.Create.ShareAccess,
- FileObject,
- &pFcb->FCBShareAccess);
if (PagingFileCreate)
{
}
else
{
+ vfatReleaseFCB (DeviceExt, ParentFcb);
return(Status);
}
}
else
{
+ if (ParentFcb)
+ {
+ vfatReleaseFCB (DeviceExt, ParentFcb);
+ }
/* Otherwise fail if the caller wanted to create a new file */
if (RequestedDisposition == FILE_CREATE)
{
pFcb = FileObject->FsContext;
+ if (pFcb->OpenHandleCount != 0 &&
+ !(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Stack->Parameters.Create.ShareAccess,
+ FileObject,
+ &pFcb->FCBShareAccess,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ VfatCloseFile (DeviceExt, FileObject);
+ return(Status);
+ }
+ }
+
/*
* Check the file has the requested attributes
*/
- if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
- pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
+ *pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
VfatCloseFile (DeviceExt, FileObject);
return(STATUS_FILE_IS_A_DIRECTORY);
}
- if (RequestedOptions & FILE_DIRECTORY_FILE &&
- !(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
+ if (RequestedOptions & FILE_DIRECTORY_FILE &&
+ !(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
{
VfatCloseFile (DeviceExt, FileObject);
return(STATUS_NOT_A_DIRECTORY);
if (PagingFileCreate)
{
/* FIXME:
- * Do more checking for page files. It is possible,
- * that the file was opened and closed previously
- * as a normal cached file. In this case, the cache
- * manager has referenced the fileobject and the fcb
- * is held in memory. Try to remove the fileobject
+ * Do more checking for page files. It is possible,
+ * that the file was opened and closed previously
+ * as a normal cached file. In this case, the cache
+ * manager has referenced the fileobject and the fcb
+ * is held in memory. Try to remove the fileobject
* from cache manager and use the fcb.
*/
if (pFcb->RefCount > 1)
return(STATUS_INVALID_PARAMETER);
}
}
-
+
if (RequestedDisposition == FILE_OVERWRITE ||
RequestedDisposition == FILE_OVERWRITE_IF)
return(Status);
}
}
-
-
+
+
/* Supersede the file */
if (RequestedDisposition == FILE_SUPERSEDE)
{
- VfatSupersedeFile(DeviceExt, FileObject, pFcb);
+ AllocationSize.QuadPart = 0;
+ VfatSetAllocationSizeInformation(FileObject, pFcb, DeviceExt, &AllocationSize);
Irp->IoStatus.Information = FILE_SUPERSEDED;
}
+ else if (RequestedDisposition == FILE_OVERWRITE || RequestedDisposition == FILE_OVERWRITE_IF)
+ {
+ Irp->IoStatus.Information = FILE_OVERWRITTEN;
+ }
else
- {
+ {
Irp->IoStatus.Information = FILE_OPENED;
}
}
-
- /* FIXME : test share access */
+
+ if (pFcb->OpenHandleCount == 0 &&
+ !(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
+ Stack->Parameters.Create.ShareAccess,
+ FileObject,
+ &pFcb->FCBShareAccess);
+ }
+ else
+ {
+ IoUpdateShareAccess(
+ FileObject,
+ &pFcb->FCBShareAccess
+ );
+
+ }
+
+ pFcb->OpenHandleCount++;
+
/* FIXME : test write access if requested */
return(Status);
*/
{
NTSTATUS Status;
-
- assert (IrpContext);
-
+
+ ASSERT(IrpContext);
+
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
/* DeviceObject represents FileSystem instead of logical volume */
VfatFreeIrpContext(IrpContext);
return(STATUS_SUCCESS);
}
-
+
if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return(VfatQueueRequest (IrpContext));
}
-
+
IrpContext->Irp->IoStatus.Information = 0;
ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE);
Status = VfatCreateFile (IrpContext->DeviceObject, IrpContext->Irp);
ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
IrpContext->Irp->IoStatus.Status = Status;
- IoCompleteRequest (IrpContext->Irp,
+ IoCompleteRequest (IrpContext->Irp,
(CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
VfatFreeIrpContext(IrpContext);
return(Status);