PFFS_FCB FFSv2AllocateFcb( IN PFFS_VCB Vcb, IN PFFS_MCB FFSMcb, IN PFFSv2_INODE dinode2) { PFFS_FCB Fcb; ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); Fcb = (PFFS_FCB)(ExAllocateFromNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList))); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); if (Fcb == NULL) { Fcb = (PFFS_FCB)ExAllocatePool(NonPagedPool, sizeof(FFS_FCB)); RtlZeroMemory(Fcb, sizeof(FFS_FCB)); SetFlag(Fcb->Flags, FCB_FROM_POOL); } else { RtlZeroMemory(Fcb, sizeof(FFS_FCB)); } if (!Fcb) { return NULL; } Fcb->Identifier.Type = FFSFCB; Fcb->Identifier.Size = sizeof(FFS_FCB); FsRtlInitializeFileLock( &Fcb->FileLockAnchor, NULL, NULL); Fcb->OpenHandleCount = 0; Fcb->ReferenceCount = 0; Fcb->Vcb = Vcb; #if DBG Fcb->AnsiFileName.MaximumLength = (USHORT) RtlxUnicodeStringToOemSize(&(FFSMcb->ShortName)) + 1; Fcb->AnsiFileName.Buffer = (PUCHAR) ExAllocatePool(PagedPool, Fcb->AnsiFileName.MaximumLength); if (!Fcb->AnsiFileName.Buffer) { goto errorout; } RtlZeroMemory(Fcb->AnsiFileName.Buffer, Fcb->AnsiFileName.MaximumLength); FFSUnicodeToOEM(&(Fcb->AnsiFileName), &(FFSMcb->ShortName)); #endif FFSMcb->FileAttr = FILE_ATTRIBUTE_NORMAL; if ((dinode2->di_mode & IFMT) == IFDIR) { SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY); } if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode2->di_mode)) { SetFlag(FFSMcb->FileAttr, FILE_ATTRIBUTE_READONLY); } Fcb->dinode2 = dinode2; Fcb->FFSMcb = FFSMcb; FFSMcb->FFSFcb = Fcb; RtlZeroMemory(&Fcb->Header, sizeof(FSRTL_COMMON_FCB_HEADER)); Fcb->Header.NodeTypeCode = (USHORT)FFSFCB; Fcb->Header.NodeByteSize = sizeof(FFS_FCB); Fcb->Header.IsFastIoPossible = FastIoIsNotPossible; Fcb->Header.Resource = &(Fcb->MainResource); Fcb->Header.PagingIoResource = &(Fcb->PagingIoResource); { ULONG Totalblocks = (ULONG)(Fcb->dinode2->di_blocks); Fcb->Header.AllocationSize.QuadPart = (((LONGLONG)FFSDataBlocks(Vcb, Totalblocks)) << BLOCK_BITS); } Fcb->Header.FileSize.QuadPart = (LONGLONG)(Fcb->dinode2->di_size); Fcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff); Fcb->SectionObject.DataSectionObject = NULL; Fcb->SectionObject.SharedCacheMap = NULL; Fcb->SectionObject.ImageSectionObject = NULL; ExInitializeResourceLite(&(Fcb->MainResource)); ExInitializeResourceLite(&(Fcb->PagingIoResource)); InsertTailList(&Vcb->FcbList, &Fcb->Next); #if DBG ExAcquireResourceExclusiveLite( &FFSGlobal->CountResource, TRUE); FFSGlobal->FcbAllocated++; ExReleaseResourceForThreadLite( &FFSGlobal->CountResource, ExGetCurrentResourceThread()); #endif return Fcb; #if DBG errorout: #endif if (Fcb) { #if DBG if (Fcb->AnsiFileName.Buffer) ExFreePool(Fcb->AnsiFileName.Buffer); #endif if (FlagOn(Fcb->Flags, FCB_FROM_POOL)) { ExFreePool(Fcb); } else { ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); ExFreeToNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList), Fcb); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); } } return NULL; }
ULONG FFSProcessDirEntry( IN PFFS_VCB Vcb, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG in, IN PVOID Buffer, IN ULONG UsedLength, IN ULONG Length, IN ULONG FileIndex, IN PUNICODE_STRING pName, IN BOOLEAN Single) { FFSv1_INODE dinode1; FFSv2_INODE dinode2; PFILE_DIRECTORY_INFORMATION FDI; PFILE_FULL_DIR_INFORMATION FFI; PFILE_BOTH_DIR_INFORMATION FBI; PFILE_NAMES_INFORMATION FNI; ULONG InfoLength = 0; ULONG NameLength = 0; ULONG dwBytes = 0; PAGED_CODE(); NameLength = pName->Length; if (!in) { FFSPrint((DBG_ERROR, "FFSPricessDirEntry: ffs_dir_entry is empty.\n")); return 0; } InfoLength = FFSGetInfoLength(FileInformationClass); if (!InfoLength || InfoLength + NameLength - sizeof(WCHAR) > Length) { FFSPrint((DBG_INFO, "FFSPricessDirEntry: Buffer is not enough.\n")); return 0; } if (FS_VERSION == 1) { if(!FFSv1LoadInode(Vcb, in, &dinode1)) { FFSPrint((DBG_ERROR, "FFSPricessDirEntry: Loading inode %xh error.\n", in)); FFSBreakPoint(); return 0; } } else { if(!FFSv2LoadInode(Vcb, in, &dinode2)) { FFSPrint((DBG_ERROR, "FFSPricessDirEntry: Loading inode %xh error.\n", in)); FFSBreakPoint(); return 0; } } switch(FileInformationClass) { case FileDirectoryInformation: FDI = (PFILE_DIRECTORY_INFORMATION) ((PUCHAR)Buffer + UsedLength); if (!Single) FDI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR); else FDI->NextEntryOffset = 0; FDI->FileIndex = FileIndex; if (FS_VERSION == 1) { FDI->CreationTime = FFSSysTime(dinode1.di_ctime); FDI->LastAccessTime = FFSSysTime(dinode1.di_atime); FDI->LastWriteTime = FFSSysTime(dinode1.di_mtime); FDI->ChangeTime = FFSSysTime(dinode1.di_mtime); FDI->EndOfFile.QuadPart = dinode1.di_size; FDI->AllocationSize.QuadPart = dinode1.di_size; FDI->FileAttributes = FILE_ATTRIBUTE_NORMAL; if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode1.di_mode)) { SetFlag(FDI->FileAttributes, FILE_ATTRIBUTE_READONLY); } if ((dinode1.di_mode & IFMT) == IFDIR) FDI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; FDI->FileNameLength = NameLength; RtlCopyMemory(FDI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; } else { FDI->CreationTime = FFSSysTime((ULONG)dinode2.di_ctime); FDI->LastAccessTime = FFSSysTime((ULONG)dinode2.di_atime); FDI->LastWriteTime = FFSSysTime((ULONG)dinode2.di_mtime); FDI->ChangeTime = FFSSysTime((ULONG)dinode2.di_mtime); FDI->EndOfFile.QuadPart = dinode2.di_size; FDI->AllocationSize.QuadPart = dinode2.di_size; FDI->FileAttributes = FILE_ATTRIBUTE_NORMAL; if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode2.di_mode)) { SetFlag(FDI->FileAttributes, FILE_ATTRIBUTE_READONLY); } if ((dinode2.di_mode & IFMT) == IFDIR) FDI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; FDI->FileNameLength = NameLength; RtlCopyMemory(FDI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; } case FileFullDirectoryInformation: FFI = (PFILE_FULL_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength); if (!Single) FFI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR); else FFI->NextEntryOffset = 0; FFI->FileIndex = FileIndex; if (FS_VERSION == 1) { FFI->CreationTime = FFSSysTime(dinode1.di_ctime); FFI->LastAccessTime = FFSSysTime(dinode1.di_atime); FFI->LastWriteTime = FFSSysTime(dinode1.di_mtime); FFI->ChangeTime = FFSSysTime(dinode1.di_mtime); FFI->EndOfFile.QuadPart = dinode1.di_size; FFI->AllocationSize.QuadPart = dinode1.di_size; FFI->FileAttributes = FILE_ATTRIBUTE_NORMAL; if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode1.di_mode)) { SetFlag(FFI->FileAttributes, FILE_ATTRIBUTE_READONLY); } if ((dinode1.di_mode & IFMT) == IFDIR) FFI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; FFI->FileNameLength = NameLength; RtlCopyMemory(FFI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; } else { FFI->CreationTime = FFSSysTime((ULONG)dinode2.di_ctime); FFI->LastAccessTime = FFSSysTime((ULONG)dinode2.di_atime); FFI->LastWriteTime = FFSSysTime((ULONG)dinode2.di_mtime); FFI->ChangeTime = FFSSysTime((ULONG)dinode2.di_mtime); FFI->EndOfFile.QuadPart = dinode2.di_size; FFI->AllocationSize.QuadPart = dinode2.di_size; FFI->FileAttributes = FILE_ATTRIBUTE_NORMAL; if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode2.di_mode)) { SetFlag(FFI->FileAttributes, FILE_ATTRIBUTE_READONLY); } if ((dinode2.di_mode & IFMT) == IFDIR) FFI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; FFI->FileNameLength = NameLength; RtlCopyMemory(FFI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; } case FileBothDirectoryInformation: FBI = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength); if (!Single) FBI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR); else FBI->NextEntryOffset = 0; if (FS_VERSION == 1) { FBI->CreationTime = FFSSysTime(dinode1.di_ctime); FBI->LastAccessTime = FFSSysTime(dinode1.di_atime); FBI->LastWriteTime = FFSSysTime(dinode1.di_mtime); FBI->ChangeTime = FFSSysTime(dinode1.di_mtime); FBI->FileIndex = FileIndex; FBI->EndOfFile.QuadPart = dinode1.di_size; FBI->AllocationSize.QuadPart = dinode1.di_size; FBI->FileAttributes = FILE_ATTRIBUTE_NORMAL; if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode1.di_mode)) { SetFlag(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY); } if ((dinode1.di_mode & IFMT) == IFDIR) FBI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; FBI->FileNameLength = NameLength; RtlCopyMemory(FBI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; } else { FBI->CreationTime = FFSSysTime((ULONG)dinode2.di_ctime); FBI->LastAccessTime = FFSSysTime((ULONG)dinode2.di_atime); FBI->LastWriteTime = FFSSysTime((ULONG)dinode2.di_mtime); FBI->ChangeTime = FFSSysTime((ULONG)dinode2.di_mtime); FBI->FileIndex = FileIndex; FBI->EndOfFile.QuadPart = dinode2.di_size; FBI->AllocationSize.QuadPart = dinode2.di_size; FBI->FileAttributes = FILE_ATTRIBUTE_NORMAL; if (FlagOn(Vcb->Flags, VCB_READ_ONLY) || FFSIsReadOnly(dinode2.di_mode)) { SetFlag(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY); } if ((dinode2.di_mode & IFMT) == IFDIR) FBI->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; FBI->FileNameLength = NameLength; RtlCopyMemory(FBI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; } case FileNamesInformation: FNI = (PFILE_NAMES_INFORMATION) ((PUCHAR)Buffer + UsedLength); if (!Single) FNI->NextEntryOffset = InfoLength + NameLength - sizeof(WCHAR); else FNI->NextEntryOffset = 0; FNI->FileNameLength = NameLength; RtlCopyMemory(FNI->FileName, pName->Buffer, NameLength); dwBytes = InfoLength + NameLength - sizeof(WCHAR); break; default: break; } return dwBytes; }