/* FUNCTIONS ****************************************************************/
+ULONGLONG
+NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
+ PFILE_RECORD_HEADER FileRecord,
+ PCWSTR Stream,
+ ULONG StreamLength,
+ PULONGLONG AllocatedSize)
+{
+ ULONGLONG Size = 0ULL;
+ ULONGLONG Allocated = 0ULL;
+ NTSTATUS Status;
+ PNTFS_ATTR_CONTEXT DataContext;
+
+ Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Stream, StreamLength, &DataContext);
+ if (NT_SUCCESS(Status))
+ {
+ Size = AttributeDataLength(&DataContext->Record);
+ Allocated = AttributeAllocatedLength(&DataContext->Record);
+ ReleaseAttributeContext(DataContext);
+ }
+
+ if (AllocatedSize != NULL) *AllocatedSize = Allocated;
+
+ return Size;
+}
+
+
static NTSTATUS
NtfsGetNameInformation(PDEVICE_EXTENSION DeviceExt,
PFILE_RECORD_HEADER FileRecord,
DPRINT("NtfsGetNameInformation() called\n");
- FileName = GetBestFileNameFromRecord(FileRecord);
+ FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
if (FileName == NULL)
{
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
- NtfsDumpFileAttributes(FileRecord);
+ NtfsDumpFileAttributes(DeviceExt, FileRecord);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
DPRINT("NtfsGetDirectoryInformation() called\n");
- FileName = GetBestFileNameFromRecord(FileRecord);
+ FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
if (FileName == NULL)
{
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
- NtfsDumpFileAttributes(FileRecord);
+ NtfsDumpFileAttributes(DeviceExt, FileRecord);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- StdInfo = GetStandardInformationFromRecord(FileRecord);
+ StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
ASSERT(StdInfo != NULL);
Length = FileName->NameLength * sizeof (WCHAR);
/* Convert file flags */
NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
- Info->EndOfFile.QuadPart = FileName->AllocatedSize;
- Info->AllocationSize.QuadPart = ROUND_UP(FileName->AllocatedSize, DeviceExt->NtfsInfo.BytesPerCluster);
+ Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
Info->FileIndex = MFTIndex;
DPRINT("NtfsGetFullDirectoryInformation() called\n");
- FileName = GetBestFileNameFromRecord(FileRecord);
+ FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
if (FileName == NULL)
{
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
- NtfsDumpFileAttributes(FileRecord);
+ NtfsDumpFileAttributes(DeviceExt, FileRecord);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- StdInfo = GetStandardInformationFromRecord(FileRecord);
+ StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
ASSERT(StdInfo != NULL);
Length = FileName->NameLength * sizeof (WCHAR);
/* Convert file flags */
NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
- Info->EndOfFile.QuadPart = FileName->AllocatedSize;
- Info->AllocationSize.QuadPart = ROUND_UP(FileName->AllocatedSize, DeviceExt->NtfsInfo.BytesPerCluster);
+ Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
Info->FileIndex = MFTIndex;
Info->EaSize = 0;
DPRINT("NtfsGetBothDirectoryInformation() called\n");
- FileName = GetBestFileNameFromRecord(FileRecord);
+ FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
if (FileName == NULL)
{
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
- NtfsDumpFileAttributes(FileRecord);
+ NtfsDumpFileAttributes(DeviceExt, FileRecord);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- ShortFileName = GetFileNameFromRecord(FileRecord, NTFS_FILE_NAME_DOS);
+ ShortFileName = GetFileNameFromRecord(DeviceExt, FileRecord, NTFS_FILE_NAME_DOS);
- StdInfo = GetStandardInformationFromRecord(FileRecord);
+ StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
ASSERT(StdInfo != NULL);
Length = FileName->NameLength * sizeof (WCHAR);
/* Convert file flags */
NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
- Info->EndOfFile.QuadPart = FileName->AllocatedSize;
- Info->AllocationSize.QuadPart = ROUND_UP(FileName->AllocatedSize, DeviceExt->NtfsInfo.BytesPerCluster);
+ Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
Info->FileIndex = MFTIndex;
Info->EaSize = 0;
FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
+ if (NtfsFCBIsCompressed(Fcb))
+ {
+ DPRINT1("Compressed directory!\n");
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ if (!ExAcquireResourceSharedLite(&Fcb->MainResource,
+ BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
+ {
+ return STATUS_PENDING;
+ }
+
if (SearchPattern != NULL)
{
if (!Ccb->DirectorySearchPattern)
ExAllocatePoolWithTag(NonPagedPool, Pattern.MaximumLength, TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
{
+ ExReleaseResourceLite(&Fcb->MainResource);
return STATUS_INSUFFICIENT_RESOURCES;
}
Ccb->DirectorySearchPattern = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
{
+ ExReleaseResourceLite(&Fcb->MainResource);
return STATUS_INSUFFICIENT_RESOURCES;
}
*/
if (MFTRecord == OldMFTRecord)
{
- DPRINT("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
+ DPRINT1("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
Ccb->Entry++;
ExFreePoolWithTag(FileRecord, TAG_NTFS);
continue;
Buffer0->NextEntryOffset = 0;
}
+ ExReleaseResourceLite(&Fcb->MainResource);
+
if (FileIndex > 0)
{
Status = STATUS_SUCCESS;
break;
}
+ if (Status == STATUS_PENDING && IrpContext->Flags & IRPCONTEXT_COMPLETE)
+ {
+ return NtfsMarkIrpContextForQueue(IrpContext);
+ }
+
IrpContext->Irp->IoStatus.Information = 0;
return Status;