-/* $Id: finfo.c,v 1.8 2001/06/12 12:35:42 ekohl Exp $
+/* $Id: finfo.c,v 1.11 2001/11/02 22:47:36 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
*/
{
PDEVICE_EXTENSION DeviceExtension;
- unsigned long AllocSize;
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
RtlZeroMemory(StandardInfo,
sizeof(FILE_STANDARD_INFORMATION));
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((FCB->entry.FileSize + DeviceExtension->BytesPerCluster - 1) /
- DeviceExtension->BytesPerCluster) *
- DeviceExtension->BytesPerCluster;
-
- StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger (AllocSize);
- StandardInfo->EndOfFile =
- RtlConvertUlongToLargeInteger (FCB->entry.FileSize);
+ StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
+ StandardInfo->EndOfFile = FCB->RFCB.FileSize;
StandardInfo->NumberOfLinks = 0;
- StandardInfo->DeletePending = FALSE;
- if ((FCB->entry.Attrib & 0x10) > 0)
- {
- StandardInfo->Directory = TRUE;
- }
- else
- {
- StandardInfo->Directory = FALSE;
- }
-
+ StandardInfo->DeletePending = FCB->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
+ StandardInfo->Directory = FCB->entry.Attrib & 0x10 ? TRUE : FALSE;
+
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
return(STATUS_SUCCESS);
}
PDEVICE_OBJECT DeviceObject,
PFILE_DISPOSITION_INFORMATION DispositionInfo)
{
+ KIRQL oldIrql;
+ VFATFCB tmpFcb;
+ WCHAR star[2];
+ ULONG Index;
+ NTSTATUS Status = STATUS_SUCCESS;
+ int count;
+
+ PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
+
DPRINT ("FsdSetDispositionInformation()\n");
- FileObject->DeletePending = DispositionInfo->DoDeleteFile;
+ assert (DeviceExt != NULL);
+ assert (DeviceExt->BytesPerCluster != 0);
+ assert (FCB != NULL);
- return (STATUS_SUCCESS);
+ if (!wcscmp(FCB->PathName, L"\\") || !wcscmp(FCB->ObjectName, L"..")
+ || !wcscmp(FCB->ObjectName, L"."))
+ {
+ // we cannot delete a '.', '..' or the root directory
+ return STATUS_ACCESS_DENIED;
+ }
+ if (DispositionInfo->DoDeleteFile)
+ {
+ KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
+ count = FCB->RefCount;
+ if (FCB->RefCount > 1)
+ Status = STATUS_ACCESS_DENIED;
+ else
+ {
+ FCB->Flags |= FCB_DELETE_PENDING;
+ FileObject->DeletePending = TRUE;
+ }
+ KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
+ DPRINT("RefCount:%d\n", count);
+ if (NT_SUCCESS(Status) && vfatFCBIsDirectory(DeviceExt, FCB))
+ {
+ memset (&tmpFcb, 0, sizeof(VFATFCB));
+ tmpFcb.ObjectName = tmpFcb.PathName;
+ star[0] = L'*';
+ star[1] = 0;
+ // skip '.' and '..', start by 2
+ Index = 2;
+ Status = FindFile (DeviceExt, &tmpFcb, FCB, star, &Index, NULL);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT1("found: \'%S\'\n", tmpFcb.PathName);
+ Status = STATUS_DIRECTORY_NOT_EMPTY;
+ FCB->Flags &= ~FCB_DELETE_PENDING;
+ FileObject->DeletePending = FALSE;
+ }
+ else
+ {
+ Status = STATUS_SUCCESS;
+ }
+ }
+ }
+ else
+ FileObject->DeletePending = FALSE;
+ return Status;
}
static NTSTATUS
return STATUS_SUCCESS;
}
+static NTSTATUS
+VfatGetInternalInformation(PVFATFCB Fcb,
+ PFILE_INTERNAL_INFORMATION InternalInfo,
+ PULONG BufferLength)
+{
+ assert (InternalInfo);
+ assert (Fcb);
+
+ if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
+ return STATUS_BUFFER_OVERFLOW;
+ // FIXME: get a real index, that can be used in a create operation
+ InternalInfo->IndexNumber.QuadPart = 0;
+ *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
+ return STATUS_SUCCESS;
+}
+
-NTSTATUS STDCALL
-VfatQueryInformation(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
/*
* FUNCTION: Retrieve the specified file information
*/
{
- PIO_STACK_LOCATION Stack;
FILE_INFORMATION_CLASS FileInformationClass;
- PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL;
-// PVFATCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
/* PRECONDITION */
- assert (DeviceObject != NULL);
- assert (Irp != NULL);
+ assert (IrpContext);
/* INITIALIZATION */
- Stack = IoGetCurrentIrpStackLocation (Irp);
- FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
- FileObject = Stack->FileObject;
-// CCB = (PVFATCCB)(FileObject->FsContext2);
-// FCB = CCB->Buffer; // Should be CCB->FCB???
- FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
-
- SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
- BufferLength = Stack->Parameters.QueryFile.Length;
-
+ FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
+ FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
+
+ SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
+ BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
+
+ if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+ {
+ if (!ExAcquireResourceSharedLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ {
+ return VfatQueueRequest (IrpContext);
+ }
+ }
+
+
switch (FileInformationClass)
{
case FileStandardInformation:
RC = VfatGetStandardInformation(FCB,
- DeviceObject,
+ IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FilePositionInformation:
- RC = VfatGetPositionInformation(FileObject,
+ RC = VfatGetPositionInformation(IrpContext->FileObject,
FCB,
- DeviceObject,
+ IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
- RC = VfatGetBasicInformation(FileObject,
+ RC = VfatGetBasicInformation(IrpContext->FileObject,
FCB,
- DeviceObject,
+ IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileNameInformation:
- RC = VfatGetNameInformation(FileObject,
+ RC = VfatGetNameInformation(IrpContext->FileObject,
FCB,
- DeviceObject,
+ IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileInternalInformation:
+ RC = VfatGetInternalInformation(FCB,
+ SystemBuffer,
+ &BufferLength);
+ break;
case FileAlternateNameInformation:
case FileAllInformation:
RC = STATUS_NOT_IMPLEMENTED;
RC = STATUS_NOT_SUPPORTED;
}
- Irp->IoStatus.Status = RC;
+ if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+ {
+ ExReleaseResourceLite(&FCB->MainResource);
+ }
+ IrpContext->Irp->IoStatus.Status = RC;
if (NT_SUCCESS(RC))
- Irp->IoStatus.Information =
- Stack->Parameters.QueryFile.Length - BufferLength;
+ IrpContext->Irp->IoStatus.Information =
+ IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
else
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
+ IrpContext->Irp->IoStatus.Information = 0;
+ IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
return RC;
}
-NTSTATUS STDCALL
-VfatSetInformation(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
/*
* FUNCTION: Retrieve the specified file information
*/
{
- PIO_STACK_LOCATION Stack;
FILE_INFORMATION_CLASS FileInformationClass;
- PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL;
-// PVFATCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS;
PVOID SystemBuffer;
/* PRECONDITION */
- assert(DeviceObject != NULL);
- assert(Irp != NULL);
+ assert(IrpContext);
- DPRINT("VfatSetInformation(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+ DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext);
/* INITIALIZATION */
- Stack = IoGetCurrentIrpStackLocation (Irp);
- FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
- FileObject = Stack->FileObject;
- FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
- SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+ FileInformationClass = IrpContext->Stack->Parameters.SetFile.FileInformationClass;
+ FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
+ SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %x\n", SystemBuffer);
+ if (FCB->Flags & FCB_IS_PAGE_FILE)
+ {
+ if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ {
+ return VfatQueueRequest (IrpContext);
+ }
+ }
+ else
+ {
+ if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
+ {
+ return VfatQueueRequest (IrpContext);
+ }
+ }
+
switch (FileInformationClass)
{
case FilePositionInformation:
- RC = VfatSetPositionInformation(FileObject,
+ RC = VfatSetPositionInformation(IrpContext->FileObject,
FCB,
- DeviceObject,
+ IrpContext->DeviceObject,
SystemBuffer);
break;
case FileDispositionInformation:
- RC = VfatSetDispositionInformation(FileObject,
+ RC = VfatSetDispositionInformation(IrpContext->FileObject,
FCB,
- DeviceObject,
+ IrpContext->DeviceObject,
SystemBuffer);
break;
case FileBasicInformation:
RC = STATUS_NOT_SUPPORTED;
}
- Irp->IoStatus.Status = RC;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
+ if (FCB->Flags & FCB_IS_PAGE_FILE)
+ {
+ ExReleaseResourceLite(&FCB->PagingIoResource);
+ }
+ else
+ {
+ ExReleaseResourceLite(&FCB->MainResource);
+ }
+
+ IrpContext->Irp->IoStatus.Status = RC;
+ IrpContext->Irp->IoStatus.Information = 0;
+ IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
return RC;
}