BOOLEAN
NtfsFCBIsDirectory(PNTFS_FCB Fcb)
{
- UNREFERENCED_PARAMETER(Fcb);
-// return(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY);
-// return(Fcb->Entry.FileFlags & 0x02);
- return TRUE;
+ return ((Fcb->Entry.FileAttributes & NTFS_FILE_TYPE_DIRECTORY) == NTFS_FILE_TYPE_DIRECTORY);
}
NtfsMakeRootFCB(PNTFS_VCB Vcb)
{
PNTFS_FCB Fcb;
+ PFILE_RECORD_HEADER MftRecord;
+ PFILENAME_ATTRIBUTE FileName;
- Fcb = NtfsCreateFCB(L"\\", Vcb);
+ MftRecord = ExAllocatePoolWithTag(NonPagedPool,
+ Vcb->NtfsInfo.BytesPerFileRecord,
+ TAG_NTFS);
+ if (MftRecord == NULL)
+ {
+ return NULL;
+ }
-// memset(Fcb->entry.Filename, ' ', 11);
+ if (!NT_SUCCESS(ReadFileRecord(Vcb, NTFS_FILE_ROOT, MftRecord)))
+ {
+ return NULL;
+ }
+
+ FileName = GetFileNameFromRecord(MftRecord);
+ if (!FileName)
+ {
+ return NULL;
+ }
+
+ Fcb = NtfsCreateFCB(L"\\", Vcb);
+ if (!Fcb)
+ {
+ return NULL;
+ }
-// Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize;
-// Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart;
-// Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY;
+ memcpy(&Fcb->Entry, FileName, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
+ Fcb->Entry.NameType = FileName->NameType;
+ Fcb->Entry.NameLength = 0;
+ Fcb->Entry.Name[0] = UNICODE_NULL;
Fcb->RefCount = 1;
Fcb->DirIndex = 0;
- Fcb->RFCB.FileSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
- Fcb->RFCB.ValidDataLength.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
- Fcb->RFCB.AllocationSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
+ Fcb->RFCB.FileSize.QuadPart = FileName->DataSize;
+ Fcb->RFCB.ValidDataLength.QuadPart = FileName->DataSize;
+ Fcb->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize;
Fcb->MFTIndex = NTFS_FILE_ROOT;
NtfsFCBInitializeCache(Vcb, Fcb);
NTSTATUS
NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb,
PNTFS_FCB DirectoryFCB,
- PWSTR Name,
+ PUNICODE_STRING Name,
PFILE_RECORD_HEADER Record,
+ ULONGLONG MFTIndex,
PNTFS_FCB * fileFCB)
{
-#if 0
- WCHAR pathName[MAX_PATH];
- PFCB rcFCB;
- ULONG Size;
+ WCHAR pathName[MAX_PATH];
+ PFILENAME_ATTRIBUTE FileName;
+ PNTFS_FCB rcFCB;
- if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
- sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
+ DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p)\n", Vcb, DirectoryFCB, Name, Record, fileFCB);
+
+ FileName = GetFileNameFromRecord(Record);
+ if (!FileName)
{
- return(STATUS_OBJECT_NAME_INVALID);
+ return STATUS_OBJECT_NAME_NOT_FOUND; // Not sure that's the best here
}
- wcscpy(pathName, DirectoryFCB->PathName);
- if (!NtfsFCBIsRoot(DirectoryFCB))
+ if (Name->Buffer[0] != 0 && wcslen(DirectoryFCB->PathName) +
+ sizeof(WCHAR) + Name->Length / sizeof(WCHAR) > MAX_PATH)
{
- wcscat(pathName, L"\\");
+ return STATUS_OBJECT_NAME_INVALID;
}
- if (Name[0] != 0)
+ wcscpy(pathName, DirectoryFCB->PathName);
+ if (!NtfsFCBIsRoot(DirectoryFCB))
{
- wcscat(pathName, Name);
+ wcscat(pathName, L"\\");
}
- else
- {
- WCHAR entryName[MAX_PATH];
+ wcscat(pathName, Name->Buffer);
- NtfsGetDirEntryName(Vcb, Record, entryName);
- wcscat(pathName, entryName);
+ rcFCB = NtfsCreateFCB(pathName, Vcb);
+ if (!rcFCB)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- rcFCB = NtfsCreateFCB(pathName, Vcb);
- memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD));
-
- Size = rcFCB->Entry.DataLengthL;
+ memcpy(&rcFCB->Entry, FileName, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
+ rcFCB->Entry.NameType = FileName->NameType;
+ rcFCB->RFCB.FileSize.QuadPart = FileName->DataSize;
+ rcFCB->RFCB.ValidDataLength.QuadPart = FileName->DataSize;
+ rcFCB->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize;
- rcFCB->RFCB.FileSize.QuadPart = Size;
- rcFCB->RFCB.ValidDataLength.QuadPart = Size;
- rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, BLOCKSIZE);
-// DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
- NtfsFCBInitializeCache(Vcb, rcFCB);
- rcFCB->RefCount++;
- NtfsAddFCBToTable(Vcb, rcFCB);
- *fileFCB = rcFCB;
+ NtfsFCBInitializeCache(Vcb, rcFCB);
+ rcFCB->RefCount = 1;
+ rcFCB->MFTIndex = MFTIndex;
+ NtfsAddFCBToTable(Vcb, rcFCB);
+ *fileFCB = rcFCB;
- return(STATUS_SUCCESS);
-#else
- return STATUS_NOT_IMPLEMENTED;
-#endif
+ return STATUS_SUCCESS;
}
UNICODE_STRING File;
PFILE_RECORD_HEADER FileRecord;
PNTFS_ATTR_CONTEXT DataContext;
+ ULONGLONG MFTIndex;
+
+ DPRINT1("NtfsDirFindFile(%p, %p, %S, %p)\n", Vcb, DirectoryFcb, FileToFind, FoundFCB);
*FoundFCB = NULL;
RtlInitUnicodeString(&File, FileToFind);
CurrentDir = DirectoryFcb->MFTIndex;
- Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, CurrentDir);
+ Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, &MFTIndex, CurrentDir);
if (!NT_SUCCESS(Status))
{
return Status;
}
- Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, FileToFind, FileRecord, FoundFCB);
+ Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, &File, FileRecord, MFTIndex, FoundFCB);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
return Status;