PNTFS_FCB NtfsMakeRootFCB(PNTFS_VCB Vcb) { PNTFS_FCB Fcb; PFILE_RECORD_HEADER MftRecord; PFILENAME_ATTRIBUTE FileName; MftRecord = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS); if (MftRecord == NULL) { return NULL; } if (!NT_SUCCESS(ReadFileRecord(Vcb, NTFS_FILE_ROOT, MftRecord))) { ExFreePoolWithTag(MftRecord, TAG_NTFS); return NULL; } FileName = GetFileNameFromRecord(Vcb, MftRecord, NTFS_FILE_NAME_WIN32); if (!FileName) { ExFreePoolWithTag(MftRecord, TAG_NTFS); return NULL; } Fcb = NtfsCreateFCB(L"\\", NULL, Vcb); if (!Fcb) { ExFreePoolWithTag(MftRecord, TAG_NTFS); 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 = FileName->DataSize; Fcb->RFCB.ValidDataLength.QuadPart = FileName->DataSize; Fcb->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize; Fcb->MFTIndex = NTFS_FILE_ROOT; Fcb->LinkCount = MftRecord->LinkCount; NtfsFCBInitializeCache(Vcb, Fcb); NtfsAddFCBToTable(Vcb, Fcb); NtfsGrabFCB(Vcb, Fcb); ExFreePoolWithTag(MftRecord, TAG_NTFS); return Fcb; }
NTSTATUS NtfsMakeFCBFromDirEntry(PVCB Vcb, PFCB DirectoryFCB, PWSTR Name, PDIR_RECORD Record, PFCB * fileFCB) { WCHAR pathName[MAX_PATH]; PFCB rcFCB; ULONG Size; if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) + sizeof(WCHAR) + wcslen (Name) > MAX_PATH) { return(STATUS_OBJECT_NAME_INVALID); } wcscpy(pathName, DirectoryFCB->PathName); if (!NtfsFCBIsRoot(DirectoryFCB)) { wcscat(pathName, L"\\"); } if (Name[0] != 0) { wcscat(pathName, Name); } else { WCHAR entryName[MAX_PATH]; NtfsGetDirEntryName(Vcb, Record, entryName); wcscat(pathName, entryName); } rcFCB = NtfsCreateFCB(pathName, Vcb); memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD)); Size = rcFCB->Entry.DataLengthL; 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; return(STATUS_SUCCESS); }
PNTFS_FCB NtfsMakeRootFCB(PNTFS_VCB Vcb) { PNTFS_FCB Fcb; Fcb = NtfsCreateFCB(L"\\", Vcb); // memset(Fcb->entry.Filename, ' ', 11); // Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize; // Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart; // Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY; 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; NtfsFCBInitializeCache(Vcb, Fcb); NtfsAddFCBToTable(Vcb, Fcb); NtfsGrabFCB(Vcb, Fcb); return Fcb; }
NTSTATUS NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb, PNTFS_FCB DirectoryFCB, PUNICODE_STRING Name, PCWSTR Stream, PFILE_RECORD_HEADER Record, ULONGLONG MFTIndex, PNTFS_FCB * fileFCB) { WCHAR pathName[MAX_PATH]; PFILENAME_ATTRIBUTE FileName; PSTANDARD_INFORMATION StdInfo; PNTFS_FCB rcFCB; ULONGLONG Size, AllocatedSize; DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p, %p)\n", Vcb, DirectoryFCB, Name, Stream, Record, fileFCB); FileName = GetBestFileNameFromRecord(Vcb, Record); if (!FileName) { return STATUS_OBJECT_NAME_NOT_FOUND; // Not sure that's the best here } if (DirectoryFCB && Name) { if (Name->Buffer[0] != 0 && wcslen(DirectoryFCB->PathName) + sizeof(WCHAR) + Name->Length / sizeof(WCHAR) > MAX_PATH) { return STATUS_OBJECT_NAME_INVALID; } wcscpy(pathName, DirectoryFCB->PathName); if (!NtfsFCBIsRoot(DirectoryFCB)) { wcscat(pathName, L"\\"); } wcscat(pathName, Name->Buffer); } else { RtlCopyMemory(pathName, FileName->Name, FileName->NameLength * sizeof (WCHAR)); pathName[FileName->NameLength] = UNICODE_NULL; } Size = NtfsGetFileSize(Vcb, Record, (Stream ? Stream : L""), (Stream ? wcslen(Stream) : 0), &AllocatedSize); rcFCB = NtfsCreateFCB(pathName, Stream, Vcb); if (!rcFCB) { return STATUS_INSUFFICIENT_RESOURCES; } memcpy(&rcFCB->Entry, FileName, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength)); rcFCB->Entry.NameType = FileName->NameType; rcFCB->RFCB.FileSize.QuadPart = Size; rcFCB->RFCB.ValidDataLength.QuadPart = Size; rcFCB->RFCB.AllocationSize.QuadPart = AllocatedSize; StdInfo = GetStandardInformationFromRecord(Vcb, Record); if (StdInfo != NULL) { rcFCB->Entry.FileAttributes |= StdInfo->FileAttribute; } NtfsFCBInitializeCache(Vcb, rcFCB); rcFCB->RefCount = 1; rcFCB->MFTIndex = MFTIndex; rcFCB->LinkCount = Record->LinkCount; NtfsAddFCBToTable(Vcb, rcFCB); *fileFCB = rcFCB; return STATUS_SUCCESS; }