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;
+ }
+
+ if (!NT_SUCCESS(ReadFileRecord(Vcb, NTFS_FILE_ROOT, MftRecord)))
+ {
+ return NULL;
+ }
-// memset(Fcb->entry.Filename, ' ', 11);
+ FileName = GetFileNameFromRecord(MftRecord);
+ if (!FileName)
+ {
+ return NULL;
+ }
-// Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize;
-// Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart;
-// Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY;
+ Fcb = NtfsCreateFCB(L"\\", Vcb);
+ if (!Fcb)
+ {
+ return NULL;
+ }
+
+ 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);
DPRINT("Name '%S'\n", Name);
}
+#endif
NTSTATUS
-NtfsMakeFCBFromDirEntry(PVCB Vcb,
- PFCB DirectoryFCB,
- PWSTR Name,
- PDIR_RECORD Record,
- PFCB * fileFCB)
+NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb,
+ PNTFS_FCB DirectoryFCB,
+ PUNICODE_STRING Name,
+ PFILE_RECORD_HEADER Record,
+ ULONGLONG MFTIndex,
+ PNTFS_FCB * fileFCB)
{
- WCHAR pathName[MAX_PATH];
- PFCB rcFCB;
- ULONG Size;
+ WCHAR pathName[MAX_PATH];
+ PFILENAME_ATTRIBUTE FileName;
+ PNTFS_FCB rcFCB;
+
+ DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p)\n", Vcb, DirectoryFCB, Name, Record, fileFCB);
- if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
- sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
+ 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);
+ return STATUS_SUCCESS;
}
-#endif
NTSTATUS
PWSTR FileToFind,
PNTFS_FCB *FoundFCB)
{
-#if 0
- WCHAR TempName[2];
- WCHAR Name[256];
- PVOID Block;
- ULONG FirstSector;
- ULONG DirSize;
- PDIR_RECORD Record;
- ULONG Offset;
- ULONG BlockOffset;
- NTSTATUS Status;
-
- LARGE_INTEGER StreamOffset;
- PVOID Context;
-
- ASSERT(DeviceExt);
- ASSERT(DirectoryFcb);
- ASSERT(FileToFind);
-
- DPRINT("NtfsDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
- DeviceExt,
- DirectoryFcb,
- FileToFind);
- DPRINT("Dir Path:%S\n", DirectoryFcb->PathName);
-
- /* default to '.' if no filename specified */
- if (wcslen(FileToFind) == 0)
- {
- TempName[0] = L'.';
- TempName[1] = 0;
- FileToFind = TempName;
- }
+ NTSTATUS Status;
+ ULONGLONG CurrentDir;
+ UNICODE_STRING File;
+ PFILE_RECORD_HEADER FileRecord;
+ PNTFS_ATTR_CONTEXT DataContext;
+ ULONGLONG MFTIndex;
- DirSize = DirectoryFcb->Entry.DataLengthL;
- StreamOffset.QuadPart = (LONGLONG)DirectoryFcb->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;
+ DPRINT1("NtfsDirFindFile(%p, %p, %S, %p)\n", Vcb, DirectoryFcb, FileToFind, FoundFCB);
- if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
- BLOCKSIZE, TRUE, &Context, &Block))
- {
- DPRINT("CcMapData() failed\n");
- return(STATUS_UNSUCCESSFUL);
- }
+ *FoundFCB = NULL;
+ RtlInitUnicodeString(&File, FileToFind);
+ CurrentDir = DirectoryFcb->MFTIndex;
- Offset = 0;
- BlockOffset = 0;
- Record = (PDIR_RECORD)Block;
- while(TRUE)
+ Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, &MFTIndex, CurrentDir);
+ if (!NT_SUCCESS(Status))
{
- if (Record->RecordLength == 0)
- {
- DPRINT("RecordLength == 0 Stopped!\n");
- break;
- }
-
- DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
- Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
-
- NtfsGetDirEntryName(DeviceExt, Record, Name);
- DPRINT("Name '%S'\n", Name);
-
- if (wstrcmpjoki(Name, FileToFind))
- {
- DPRINT("Match found, %S\n", Name);
- Status = NtfsMakeFCBFromDirEntry(DeviceExt,
- DirectoryFcb,
- Name,
- Record,
- FoundFCB);
-
- CcUnpinData(Context);
-
- return(Status);
- }
-
- Offset += Record->RecordLength;
- BlockOffset += Record->RecordLength;
- Record = (PDIR_RECORD)(Block + BlockOffset);
- if (BlockOffset >= BLOCKSIZE || Record->RecordLength == 0)
- {
- DPRINT("Map next sector\n");
- CcUnpinData(Context);
- StreamOffset.QuadPart += BLOCKSIZE;
- Offset = ROUND_UP(Offset, BLOCKSIZE);
- BlockOffset = 0;
-
- if (!CcMapData(DeviceExt->StreamFileObject,
- &StreamOffset,
- BLOCKSIZE, TRUE,
- &Context, &Block))
- {
- DPRINT("CcMapData() failed\n");
- return(STATUS_UNSUCCESSFUL);
- }
- Record = (PDIR_RECORD)(Block + BlockOffset);
- }
-
- if (Offset >= DirSize)
- break;
+ return Status;
}
- CcUnpinData(Context);
-#else
- UNREFERENCED_PARAMETER(Vcb);
- UNREFERENCED_PARAMETER(DirectoryFcb);
- UNREFERENCED_PARAMETER(FileToFind);
- UNREFERENCED_PARAMETER(FoundFCB);
-#endif
- return STATUS_OBJECT_NAME_NOT_FOUND;
+ Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, &File, FileRecord, MFTIndex, FoundFCB);
+ ExFreePoolWithTag(FileRecord, TAG_NTFS);
+
+ return Status;
}