StandardInfo->EndOfFile = FCB->RFCB.FileSize;
StandardInfo->Directory = FALSE;
}
- StandardInfo->NumberOfLinks = 0;
+ StandardInfo->NumberOfLinks = 1;
StandardInfo->DeletePending = FCB->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
PFILE_POSITION_INFORMATION PositionInfo,
PULONG BufferLength)
{
+ UNREFERENCED_PARAMETER(FileObject);
+ UNREFERENCED_PARAMETER(FCB);
+ UNREFERENCED_PARAMETER(DeviceObject);
+
DPRINT ("VfatGetPositionInformation()\n");
if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
ASSERT(NULL != DeviceExt);
ASSERT(NULL != BasicInfo);
/* Check volume label bit */
- ASSERT(0 == (*FCB->Attributes & 0x08));
+ ASSERT(0 == (*FCB->Attributes & _A_VOLID));
if (FCB->Flags & FCB_IS_FATX_ENTRY)
{
PULONG BufferLength)
{
PDEVICE_EXTENSION DeviceExt;
+
+ UNREFERENCED_PARAMETER(FileObject);
+
DPRINT("VfatGetBasicInformation()\n");
DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
PDEVICE_OBJECT DeviceObject,
PFILE_DISPOSITION_INFORMATION DispositionInfo)
{
-#ifdef DBG
+#if DBG
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
#endif
- DPRINT ("FsdSetDispositionInformation()\n");
+ DPRINT ("FsdSetDispositionInformation(<%wZ>, Delete %d)\n", &FCB->PathNameU, DispositionInfo->DeleteFile);
ASSERT(DeviceExt != NULL);
ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
* FUNCTION: Retrieve the file name information
*/
{
+ ULONG BytesToCopy;
+
+ UNREFERENCED_PARAMETER(FileObject);
+ UNREFERENCED_PARAMETER(DeviceObject);
+
ASSERT(NameInfo != NULL);
ASSERT(FCB != NULL);
- NameInfo->FileNameLength = FCB->PathNameU.Length;
- if (*BufferLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length)
+ /* If buffer can't hold at least the file name length, bail out */
+ if (*BufferLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
return STATUS_BUFFER_OVERFLOW;
- RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
+ /* Save file name length, and as much file len, as buffer length allows */
+ NameInfo->FileNameLength = FCB->PathNameU.Length;
+
+ /* Calculate amount of bytes to copy not to overflow the buffer */
+ BytesToCopy = min(FCB->PathNameU.Length,
+ *BufferLength - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]));
+ /* Fill in the bytes */
+ RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, BytesToCopy);
+
+ /* Check if we could write more but are not able to */
+ if (*BufferLength < FCB->PathNameU.Length + (ULONG)FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
+ {
+ /* Return number of bytes written */
+ *BufferLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + BytesToCopy;
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ /* We filled up as many bytes, as needed */
*BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + FCB->PathNameU.Length);
return STATUS_SUCCESS;
{
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
+ UNREFERENCED_PARAMETER(FileObject);
+ UNREFERENCED_PARAMETER(Fcb);
+
/* FIXME - use SEH to access the buffer! */
Info->EaSize = 0;
*BufferLength -= sizeof(*Info);
Fcb->RFCB.FileSize.QuadPart = Size;
Fcb->RFCB.ValidDataLength.QuadPart = Size;
- if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
- {
- CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
- }
+ CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
}
NTSTATUS
ULONG NCluster;
BOOLEAN AllocSizeChanged = FALSE;
- DPRINT("VfatSetAllocationSizeInformation()\n");
+ DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %d)\n", &Fcb->PathNameU,
+ AllocationSize->HighPart, AllocationSize->LowPart);
if (Fcb->Flags & FCB_IS_FATX_ENTRY)
OldSize = Fcb->entry.FatX.FileSize;
}
else
{
-#if 0 /* FIXME */
if (Fcb->LastCluster > 0)
{
if (Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize == Fcb->LastOffset)
return Status;
}
- if (Fcb->LastCluster == 0)
- {
- Fcb->LastCluster = Cluster;
- Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
- }
+ Fcb->LastCluster = Cluster;
+ Fcb->LastOffset = Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize;
/* FIXME: Check status */
/* Cluster points now to the last cluster within the chain */
Status = OffsetToCluster(DeviceExt, Cluster,
ROUND_DOWN(NewSize - 1, ClusterSize) - Fcb->LastOffset,
&NCluster, TRUE);
-#else
- Status = OffsetToCluster(DeviceExt, FirstCluster,
- ROUND_DOWN(NewSize - 1, ClusterSize),
- &Cluster, TRUE);
- NCluster = Cluster;
-#endif
if (NCluster == 0xffffffff || !NT_SUCCESS(Status))
{
/* disk is full */
}
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{
+
+ DPRINT("Check for the ability to set file size\n");
+ if (!MmCanFileBeTruncated
+ (FileObject->SectionObjectPointer,
+ (PLARGE_INTEGER)AllocationSize))
+ {
+ DPRINT("Couldn't set file size!\n");
+ return STATUS_USER_MAPPED_FILE;
+ }
+ DPRINT("Can set file size\n");
+
AllocSizeChanged = TRUE;
/* FIXME: Use the cached cluster/offset better way. */
Fcb->LastCluster = Fcb->LastOffset = 0;
FILE_INFORMATION_CLASS FileInformationClass;
PVFATFCB FCB = NULL;
- NTSTATUS RC = STATUS_SUCCESS;
+ NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
switch (FileInformationClass)
{
case FileStandardInformation:
- RC = VfatGetStandardInformation(FCB,
+ Status = VfatGetStandardInformation(FCB,
SystemBuffer,
&BufferLength);
break;
case FilePositionInformation:
- RC = VfatGetPositionInformation(IrpContext->FileObject,
+ Status = VfatGetPositionInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
- RC = VfatGetBasicInformation(IrpContext->FileObject,
+ Status = VfatGetBasicInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileNameInformation:
- RC = VfatGetNameInformation(IrpContext->FileObject,
+ Status = VfatGetNameInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileInternalInformation:
- RC = VfatGetInternalInformation(FCB,
+ Status = VfatGetInternalInformation(FCB,
SystemBuffer,
&BufferLength);
break;
case FileNetworkOpenInformation:
- RC = VfatGetNetworkOpenInformation(FCB,
+ Status = VfatGetNetworkOpenInformation(FCB,
IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileAllInformation:
- RC = VfatGetAllInformation(IrpContext->FileObject,
+ Status = VfatGetAllInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
break;
case FileEaInformation:
- RC = VfatGetEaInformation(IrpContext->FileObject,
+ Status = VfatGetEaInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
break;
case FileAlternateNameInformation:
- RC = STATUS_NOT_IMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
break;
default:
- RC = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
}
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
ExReleaseResourceLite(&FCB->MainResource);
}
- IrpContext->Irp->IoStatus.Status = RC;
- if (NT_SUCCESS(RC))
+ IrpContext->Irp->IoStatus.Status = Status;
+ if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
IrpContext->Irp->IoStatus.Information =
IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
else
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
- return RC;
+ return Status;
}
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
+ /* Special: We should call MmCanFileBeTruncated here to determine if changing
+ the file size would be allowed. If not, we bail with the right error.
+ We must do this before acquiring the lock. */
+ if (FileInformationClass == FileEndOfFileInformation)
+ {
+ DPRINT("Check for the ability to set file size\n");
+ if (!MmCanFileBeTruncated
+ (IrpContext->FileObject->SectionObjectPointer,
+ (PLARGE_INTEGER)SystemBuffer))
+ {
+ DPRINT("Couldn't set file size!\n");
+ IrpContext->Irp->IoStatus.Status = STATUS_USER_MAPPED_FILE;
+ IrpContext->Irp->IoStatus.Information = 0;
+ IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
+ return STATUS_USER_MAPPED_FILE;
+ }
+ DPRINT("Can set file size\n");
+ }
+
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource,