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; }
static NTSTATUS NtfsMountVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_OBJECT NewDeviceObject = NULL; PDEVICE_OBJECT DeviceToMount; PIO_STACK_LOCATION Stack; PNTFS_FCB Fcb = NULL; PNTFS_CCB Ccb = NULL; PNTFS_VCB Vcb = NULL; NTSTATUS Status; DPRINT1("NtfsMountVolume() called\n"); if (DeviceObject != NtfsGlobalData->DeviceObject) { Status = STATUS_INVALID_DEVICE_REQUEST; goto ByeBye; } Stack = IoGetCurrentIrpStackLocation(Irp); DeviceToMount = Stack->Parameters.MountVolume.DeviceObject; Status = NtfsHasFileSystem(DeviceToMount); if (!NT_SUCCESS(Status)) { goto ByeBye; } Status = IoCreateDevice(NtfsGlobalData->DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &NewDeviceObject); if (!NT_SUCCESS(Status)) goto ByeBye; NewDeviceObject->Flags |= DO_DIRECT_IO; Vcb = (PVOID)NewDeviceObject->DeviceExtension; RtlZeroMemory(Vcb, sizeof(NTFS_VCB)); Vcb->Identifier.Type = NTFS_TYPE_VCB; Vcb->Identifier.Size = sizeof(NTFS_TYPE_VCB); Status = NtfsGetVolumeData(DeviceToMount, Vcb); if (!NT_SUCCESS(Status)) goto ByeBye; NewDeviceObject->Vpb = DeviceToMount->Vpb; Vcb->StorageDevice = DeviceToMount; Vcb->StorageDevice->Vpb->DeviceObject = NewDeviceObject; Vcb->StorageDevice->Vpb->RealDevice = Vcb->StorageDevice; Vcb->StorageDevice->Vpb->Flags |= VPB_MOUNTED; NewDeviceObject->StackSize = Vcb->StorageDevice->StackSize + 1; NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; Vcb->StreamFileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice); InitializeListHead(&Vcb->FcbListHead); Fcb = NtfsCreateFCB(NULL, Vcb); if (Fcb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB); if (Ccb == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto ByeBye; } RtlZeroMemory(Ccb, sizeof(NTFS_CCB)); Ccb->Identifier.Type = NTFS_TYPE_CCB; Ccb->Identifier.Size = sizeof(NTFS_TYPE_CCB); Vcb->StreamFileObject->FsContext = Fcb; Vcb->StreamFileObject->FsContext2 = Ccb; Vcb->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; Vcb->StreamFileObject->PrivateCacheMap = NULL; Vcb->StreamFileObject->Vpb = Vcb->Vpb; Ccb->PtrFileObject = Vcb->StreamFileObject; Fcb->FileObject = Vcb->StreamFileObject; Fcb->Vcb = (PDEVICE_EXTENSION)Vcb->StorageDevice; Fcb->Flags = FCB_IS_VOLUME_STREAM; Fcb->RFCB.FileSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; Fcb->RFCB.ValidDataLength.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; Fcb->RFCB.AllocationSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; /* Correct? */ // Fcb->Entry.ExtentLocationL = 0; // Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE; CcInitializeCacheMap(Vcb->StreamFileObject, (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), FALSE, &(NtfsGlobalData->CacheMgrCallbacks), Fcb); ExInitializeResourceLite(&Vcb->DirResource); KeInitializeSpinLock(&Vcb->FcbListLock); /* Get serial number */ NewDeviceObject->Vpb->SerialNumber = Vcb->NtfsInfo.SerialNumber; /* Get volume label */ NewDeviceObject->Vpb->VolumeLabelLength = Vcb->NtfsInfo.VolumeLabelLength; RtlCopyMemory(NewDeviceObject->Vpb->VolumeLabel, Vcb->NtfsInfo.VolumeLabel, Vcb->NtfsInfo.VolumeLabelLength); Status = STATUS_SUCCESS; ByeBye: if (!NT_SUCCESS(Status)) { /* Cleanup */ if (Vcb && Vcb->StreamFileObject) ObDereferenceObject(Vcb->StreamFileObject); if (Fcb) ExFreePool(Fcb); if (Ccb) ExFreePool(Ccb); if (NewDeviceObject) IoDeleteDevice(NewDeviceObject); } DPRINT("NtfsMountVolume() done (Status: %lx)\n", Status); return Status; }
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; }