StandardInfo->Directory = FALSE;
}
StandardInfo->NumberOfLinks = 1;
- StandardInfo->DeletePending = BooleanFlagOn(FCB->Flags, FCB_DELETE_PENDING) ? TRUE : FALSE;
+ StandardInfo->DeletePending = BooleanFlagOn(FCB->Flags, FCB_DELETE_PENDING);
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
return STATUS_SUCCESS;
VfatGetPositionInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB,
- PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_POSITION_INFORMATION PositionInfo,
PULONG BufferLength)
{
UNREFERENCED_PARAMETER(FileObject);
UNREFERENCED_PARAMETER(FCB);
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(DeviceExt);
DPRINT("VfatGetPositionInformation()\n");
PDEVICE_EXTENSION DeviceExt,
PFILE_BASIC_INFORMATION BasicInfo)
{
+ ULONG NotifyFilter;
+
DPRINT("VfatSetBasicInformation()\n");
ASSERT(NULL != FileObject);
/* Check volume label bit */
ASSERT(0 == (*FCB->Attributes & _A_VOLID));
- if (FCB->Flags & FCB_IS_FATX_ENTRY)
+ NotifyFilter = 0;
+
+ if (BasicInfo->FileAttributes != 0)
+ {
+ UCHAR Attributes;
+
+ Attributes = (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_ARCHIVE |
+ FILE_ATTRIBUTE_SYSTEM |
+ FILE_ATTRIBUTE_HIDDEN |
+ FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_READONLY));
+
+ if (vfatFCBIsDirectory(FCB))
+ {
+ Attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ }
+ else
+ {
+ if (BooleanFlagOn(BasicInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
+ {
+ DPRINT("Setting directory attribute on a file!\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ if (Attributes != *FCB->Attributes)
+ {
+ *FCB->Attributes = Attributes;
+ DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+ }
+ }
+
+ if (vfatVolumeIsFatX(DeviceExt))
{
if (BasicInfo->CreationTime.QuadPart != 0 && BasicInfo->CreationTime.QuadPart != -1)
{
&BasicInfo->CreationTime,
&FCB->entry.FatX.CreationDate,
&FCB->entry.FatX.CreationTime);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
}
if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
&BasicInfo->LastAccessTime,
&FCB->entry.FatX.AccessDate,
&FCB->entry.FatX.AccessTime);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
&BasicInfo->LastWriteTime,
&FCB->entry.FatX.UpdateDate,
&FCB->entry.FatX.UpdateTime);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
}
}
else
&BasicInfo->CreationTime,
&FCB->entry.Fat.CreationDate,
&FCB->entry.Fat.CreationTime);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
}
if (BasicInfo->LastAccessTime.QuadPart != 0 && BasicInfo->LastAccessTime.QuadPart != -1)
&BasicInfo->LastAccessTime,
&FCB->entry.Fat.AccessDate,
NULL);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if (BasicInfo->LastWriteTime.QuadPart != 0 && BasicInfo->LastWriteTime.QuadPart != -1)
&BasicInfo->LastWriteTime,
&FCB->entry.Fat.UpdateDate,
&FCB->entry.Fat.UpdateTime);
+ NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
}
}
- if (BasicInfo->FileAttributes)
+ VfatUpdateEntry(FCB, vfatVolumeIsFatX(DeviceExt));
+
+ if (NotifyFilter != 0)
{
- *FCB->Attributes = (unsigned char)((*FCB->Attributes &
- (FILE_ATTRIBUTE_DIRECTORY | 0x48)) |
- (BasicInfo->FileAttributes &
- (FILE_ATTRIBUTE_ARCHIVE |
- FILE_ATTRIBUTE_SYSTEM |
- FILE_ATTRIBUTE_HIDDEN |
- FILE_ATTRIBUTE_READONLY)));
- DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
+ FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
+ &(DeviceExt->NotifyList),
+ (PSTRING)&FCB->PathNameU,
+ FCB->PathNameU.Length - FCB->LongNameU.Length,
+ NULL, NULL, NotifyFilter, FILE_ACTION_MODIFIED,
+ NULL);
}
- VfatUpdateEntry(FCB);
-
return STATUS_SUCCESS;
}
VfatGetBasicInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB,
- PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_BASIC_INFORMATION BasicInfo,
PULONG BufferLength)
{
- PDEVICE_EXTENSION DeviceExt;
-
UNREFERENCED_PARAMETER(FileObject);
DPRINT("VfatGetBasicInformation()\n");
- DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
- if (FCB->Flags & FCB_IS_FATX_ENTRY)
+ if (vfatVolumeIsFatX(DeviceExt))
{
FsdDosDateTimeToSystemTime(DeviceExt,
FCB->entry.FatX.CreationDate,
VfatSetDispositionInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB,
- PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_DISPOSITION_INFORMATION DispositionInfo)
{
-#if DBG
- PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
-#endif
-
DPRINT("FsdSetDispositionInformation(<%wZ>, Delete %u)\n", &FCB->PathNameU, DispositionInfo->DeleteFile);
ASSERT(DeviceExt != NULL);
return STATUS_SUCCESS;
}
- if (FCB->Flags & FCB_DELETE_PENDING)
+ if (BooleanFlagOn(FCB->Flags, FCB_DELETE_PENDING))
{
/* stream already marked for deletion. just update the file object */
FileObject->DeletePending = TRUE;
return STATUS_SUCCESS;
}
- if (*FCB->Attributes & FILE_ATTRIBUTE_READONLY)
+ if (vfatFCBIsReadOnly(FCB))
{
return STATUS_CANNOT_DELETE;
}
return STATUS_CANNOT_DELETE;
}
- if (vfatFCBIsDirectory(FCB) && !VfatIsDirectoryEmpty(FCB))
+ if (vfatFCBIsDirectory(FCB) && !VfatIsDirectoryEmpty(DeviceExt, FCB))
{
/* can't delete a non-empty directory */
if (ReplaceIfExists)
{
/* If that's a directory or a read-only file, we're not allowed */
- if (vfatFCBIsDirectory(TargetFcb) || ((*TargetFcb->Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY))
+ if (vfatFCBIsDirectory(TargetFcb) || vfatFCBIsReadOnly(TargetFcb))
{
DPRINT("And this is a readonly file!\n");
vfatReleaseFCB(DeviceExt, *ParentFCB);
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
- ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
+ (vfatFCBIsDirectory(FCB) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_OLD_NAME,
NULL);
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
- ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
+ (vfatFCBIsDirectory(FCB) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_NEW_NAME,
NULL);
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
- ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
+ (vfatFCBIsDirectory(FCB) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
(DeletedTarget ? FILE_ACTION_REMOVED : FILE_ACTION_RENAMED_OLD_NAME),
NULL);
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
- ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
+ (vfatFCBIsDirectory(FCB) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_NEW_NAME,
NULL);
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
- ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
+ (vfatFCBIsDirectory(FCB) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_REMOVED,
NULL);
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
- ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
+ (vfatFCBIsDirectory(FCB) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_ADDED,
NULL);
VfatGetNameInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB,
- PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_NAME_INFORMATION NameInfo,
PULONG BufferLength)
{
ULONG BytesToCopy;
UNREFERENCED_PARAMETER(FileObject);
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(DeviceExt);
ASSERT(NameInfo != NULL);
ASSERT(FCB != NULL);
NTSTATUS
VfatGetInternalInformation(
PVFATFCB Fcb,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_INTERNAL_INFORMATION InternalInfo,
PULONG BufferLength)
{
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;
+
+ InternalInfo->IndexNumber.QuadPart = (LONGLONG)vfatDirEntryGetFirstCluster(DeviceExt, &Fcb->entry) * DeviceExt->FatInfo.BytesPerCluster;
+
*BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
return STATUS_SUCCESS;
}
if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
- if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ if (vfatVolumeIsFatX(DeviceExt))
{
FsdDosDateTimeToSystemTime(DeviceExt,
Fcb->entry.FatX.CreationDate,
VfatGetEaInformation(
PFILE_OBJECT FileObject,
PVFATFCB Fcb,
- PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_EA_INFORMATION Info,
PULONG BufferLength)
{
- PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
-
UNREFERENCED_PARAMETER(FileObject);
UNREFERENCED_PARAMETER(Fcb);
VfatGetAllInformation(
PFILE_OBJECT FileObject,
PVFATFCB Fcb,
- PDEVICE_OBJECT DeviceObject,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_ALL_INFORMATION Info,
PULONG BufferLength)
{
return STATUS_BUFFER_OVERFLOW;
/* Basic Information */
- Status = VfatGetBasicInformation(FileObject, Fcb, DeviceObject, &Info->BasicInformation, BufferLength);
+ Status = VfatGetBasicInformation(FileObject, Fcb, DeviceExt, &Info->BasicInformation, BufferLength);
if (!NT_SUCCESS(Status)) return Status;
/* Standard Information */
Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
if (!NT_SUCCESS(Status)) return Status;
/* Internal Information */
- Status = VfatGetInternalInformation(Fcb, &Info->InternalInformation, BufferLength);
+ Status = VfatGetInternalInformation(Fcb, DeviceExt, &Info->InternalInformation, BufferLength);
if (!NT_SUCCESS(Status)) return Status;
/* EA Information */
- Status = VfatGetEaInformation(FileObject, Fcb, DeviceObject, &Info->EaInformation, BufferLength);
+ Status = VfatGetEaInformation(FileObject, Fcb, DeviceExt, &Info->EaInformation, BufferLength);
if (!NT_SUCCESS(Status)) return Status;
/* Access Information: The IO-Manager adds this information */
*BufferLength -= sizeof(FILE_ACCESS_INFORMATION);
/* Position Information */
- Status = VfatGetPositionInformation(FileObject, Fcb, DeviceObject, &Info->PositionInformation, BufferLength);
+ Status = VfatGetPositionInformation(FileObject, Fcb, DeviceExt, &Info->PositionInformation, BufferLength);
if (!NT_SUCCESS(Status)) return Status;
/* Mode Information: The IO-Manager adds this information */
*BufferLength -= sizeof(FILE_MODE_INFORMATION);
/* Alignment Information: The IO-Manager adds this information */
*BufferLength -= sizeof(FILE_ALIGNMENT_INFORMATION);
/* Name Information */
- Status = VfatGetNameInformation(FileObject, Fcb, DeviceObject, &Info->NameInformation, BufferLength);
+ Status = VfatGetNameInformation(FileObject, Fcb, DeviceExt, &Info->NameInformation, BufferLength);
return Status;
}
PFILE_OBJECT FileObject,
PVFATFCB Fcb,
ULONG Size,
- ULONG ClusterSize)
+ ULONG ClusterSize,
+ BOOLEAN IsFatX)
{
if (Size > 0)
{
}
if (!vfatFCBIsDirectory(Fcb))
{
- if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ if (IsFatX)
Fcb->entry.FatX.FileSize = Size;
else
Fcb->entry.Fat.FileSize = Size;
ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
ULONG NewSize = AllocationSize->u.LowPart;
ULONG NCluster;
- BOOLEAN AllocSizeChanged = FALSE;
+ BOOLEAN AllocSizeChanged = FALSE, IsFatX = vfatVolumeIsFatX(DeviceExt);
DPRINT("VfatSetAllocationSizeInformation(File <%wZ>, AllocationSize %d %u)\n",
&Fcb->PathNameU, AllocationSize->HighPart, AllocationSize->LowPart);
- if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ if (IsFatX)
OldSize = Fcb->entry.FatX.FileSize;
else
OldSize = Fcb->entry.Fat.FileSize;
return STATUS_DISK_FULL;
}
- if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ if (IsFatX)
{
Fcb->entry.FatX.FirstCluster = FirstCluster;
}
return STATUS_DISK_FULL;
}
}
- UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize);
+ UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize, vfatVolumeIsFatX(DeviceExt));
}
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{
AllocSizeChanged = TRUE;
/* FIXME: Use the cached cluster/offset better way. */
Fcb->LastCluster = Fcb->LastOffset = 0;
- UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize);
+ UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize, vfatVolumeIsFatX(DeviceExt));
if (NewSize > 0)
{
Status = OffsetToCluster(DeviceExt, FirstCluster,
}
else
{
- if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ if (IsFatX)
{
Fcb->entry.FatX.FirstCluster = 0;
}
}
else
{
- UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize);
+ UpdateFileSize(FileObject, Fcb, NewSize, ClusterSize, vfatVolumeIsFatX(DeviceExt));
}
/* Update the on-disk directory entry */
Fcb->Flags |= FCB_IS_DIRTY;
if (AllocSizeChanged)
{
- VfatUpdateEntry(Fcb);
+ VfatUpdateEntry(Fcb, vfatVolumeIsFatX(DeviceExt));
}
return STATUS_SUCCESS;
}
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
- if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+ if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceSharedLite(&FCB->MainResource,
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
case FilePositionInformation:
Status = VfatGetPositionInformation(IrpContext->FileObject,
FCB,
- IrpContext->DeviceObject,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
Status = VfatGetBasicInformation(IrpContext->FileObject,
FCB,
- IrpContext->DeviceObject,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileNameInformation:
Status = VfatGetNameInformation(IrpContext->FileObject,
FCB,
- IrpContext->DeviceObject,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileInternalInformation:
Status = VfatGetInternalInformation(FCB,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileAllInformation:
Status = VfatGetAllInformation(IrpContext->FileObject,
FCB,
- IrpContext->DeviceObject,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileEaInformation:
Status = VfatGetEaInformation(IrpContext->FileObject,
FCB,
- IrpContext->DeviceObject,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
Status = STATUS_INVALID_PARAMETER;
}
- if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+ if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
{
ExReleaseResourceLite(&FCB->MainResource);
}
}
}
- if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+ if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource,
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
case FileDispositionInformation:
Status = VfatSetDispositionInformation(IrpContext->FileObject,
FCB,
- IrpContext->DeviceObject,
+ IrpContext->DeviceExt,
SystemBuffer);
break;
Status = STATUS_NOT_SUPPORTED;
}
- if (!(FCB->Flags & FCB_IS_PAGE_FILE))
+ if (!BooleanFlagOn(FCB->Flags, FCB_IS_PAGE_FILE))
{
ExReleaseResourceLite(&FCB->MainResource);
}