VOID FatPrepareWriteVolumeFile ( IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer, IN BOOLEAN Reversible, IN BOOLEAN Zero ) /*++ Routine Description: This routine first looks to see if the specified range of sectors, is already in the cache. If so, it increments the BCB PinCount, sets the BCB dirty, and returns with the location of the sectors. If the sectors are not in the cache and Wait is TRUE, it finds a free BCB (potentially causing a flush), and clears out the entire buffer. Once this is done, it increments the BCB PinCount, sets the BCB dirty, and returns with the location of the sectors. If the sectors are not in the cache and Wait is FALSE, this routine raises STATUS_CANT_WAIT. Arguments: Vcb - Pointer to the VCB for the volume StartingVbo - The virtual offset of the first byte to be written ByteCount - Number of bytes to be written Bcb - Returns a pointer to the BCB which is valid until unpinned Buffer - Returns a pointer to the sectors, which is valid until unpinned Reversible - Supplies TRUE if the specified range of modification should be repinned so that the operation can be reversed in a controlled fashion if errors are encountered. Zero - Supplies TRUE if the specified range of bytes should be zeroed --*/ { LARGE_INTEGER Vbo; PAGED_CODE(); // // Check to see that all references are within the Bios Parameter Block // or the fat(s). // ASSERT( ((StartingVbo + ByteCount) <= (ULONG) (FatRootDirectoryLbo( &Vcb->Bpb )))); DebugTrace(+1, Dbg, "FatPrepareWriteVolumeFile\n", 0); DebugTrace( 0, Dbg, "Vcb = %08lx\n", Vcb); DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", (ULONG)StartingVbo); DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount); DebugTrace( 0, Dbg, "Zero = %08lx\n", Zero); // // Call the Cache manager to attempt the transfer. // Vbo.QuadPart = StartingVbo; if (!CcPinRead( Vcb->VirtualVolumeFile, &Vbo, ByteCount, BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT), Bcb, Buffer )) { ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); // // Could not read the data without waiting (cache miss). // FatRaiseStatus( IrpContext, STATUS_CANT_WAIT ); } // // This keeps the data pinned until we complete the request // and writes the dirty bit through to the disk. // DbgDoit( IrpContext->PinCount += 1 ) try { if (Zero) { RtlZeroMemory( *Buffer, ByteCount ); } FatSetDirtyBcb( IrpContext, *Bcb, Vcb, Reversible ); } finally { if (AbnormalTermination()) { FatUnpinBcb(IrpContext, *Bcb); } } DebugTrace(-1, Dbg, "FatPrepareWriteVolumeFile -> VOID, *Bcb = %08lx\n", *Bcb); return; }
VOID FatReadVolumeFile ( IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer ) /*++ Routine Description: This routine is called when the specified range of sectors is to be read into the cache. In fat, the volume file only contains the boot sector, reserved sectors, and the "fat(s)." Thus the volume file is of fixed size and only extends up to (but not not including) the root directory entry, and will never move or change size. The fat volume file is also peculiar in that, since it starts at the logical beginning of the disk, Vbo == Lbo. Arguments: Vcb - Pointer to the VCB for the volume StartingVbo - The virtual offset of the first desired byte ByteCount - Number of bytes desired Bcb - Returns a pointer to the BCB which is valid until unpinned Buffer - Returns a pointer to the sectors, which is valid until unpinned --*/ { LARGE_INTEGER Vbo; PAGED_CODE(); // // Check to see that all references are within the Bios Parameter Block // or the fat(s). A special case is made when StartingVbo == 0 at // mounting time since we do not know how big the fat is. // ASSERT( ((StartingVbo == 0) || ((StartingVbo + ByteCount) <= (ULONG) (FatRootDirectoryLbo( &Vcb->Bpb ) + PAGE_SIZE)))); DebugTrace(+1, Dbg, "FatReadVolumeFile\n", 0); DebugTrace( 0, Dbg, "Vcb = %08lx\n", Vcb); DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo); DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount); // // Call the Cache manager to attempt the transfer. // Vbo.QuadPart = StartingVbo; if (!CcMapData( Vcb->VirtualVolumeFile, &Vbo, ByteCount, BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT), Bcb, Buffer )) { ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); // // Could not read the data without waiting (cache miss). // FatRaiseStatus( IrpContext, STATUS_CANT_WAIT ); } DbgDoit( IrpContext->PinCount += 1 ) DebugTrace(-1, Dbg, "FatReadVolumeFile -> VOID, *BCB = %08lx\n", *Bcb); return; }
VOID NTAPI FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb) { PFCB Dcb; /* Make sure it's not already created */ ASSERT(!Vcb->RootDcb); /* Allocate the DCB */ Dcb = FsRtlAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB); /* Zero it */ RtlZeroMemory(Dcb, sizeof(FCB)); /* Assign it to the VCB */ Vcb->RootDcb = Dcb; /* Set its header */ Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB; Dcb->Header.NodeByteSize = sizeof(FCB); /* FCB is in a good condition */ Dcb->Condition = FcbGood; /* Initialize FCB's resource */ Dcb->Header.Resource = &Dcb->Resource; ExInitializeResourceLite(&Dcb->Resource); /* Initialize Paging Io resource*/ Dcb->Header.PagingIoResource = &Dcb->PagingIoResource; ExInitializeResourceLite(&Dcb->PagingIoResource); /* Initialize a list of parent DCBs*/ InitializeListHead(&Dcb->ParentDcbLinks); /* Set VCB */ Dcb->Vcb = Vcb; /* Initialize parent's DCB list */ InitializeListHead(&Dcb->Dcb.ParentDcbList); /* Initialize the full file name */ Dcb->FullFileName.Buffer = L"\\"; Dcb->FullFileName.Length = 1 * sizeof(WCHAR); Dcb->FullFileName.MaximumLength = 2 * sizeof(WCHAR); Dcb->ShortName.Name.Ansi.Buffer = "\\"; Dcb->ShortName.Name.Ansi.Length = 1; Dcb->ShortName.Name.Ansi.MaximumLength = 2 * sizeof(CHAR); /* Fill dirent attribute byte copy */ Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY; /* Initialize advanced FCB header fields */ ExInitializeFastMutex(&Dcb->HeaderMutex); FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex); /* Set up first cluster field depending on FAT type */ if (TRUE/*FatIsFat32(Vcb)*/) { /* First cluster is really the first cluster of this volume */ Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster; /* Calculate size of FAT32 root dir */ Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF; //FatLookupFileAllocationSize(IrpContext, Dcb); DPRINT1("Calculation of a size of a root dir is missing!\n"); Dcb->Header.FileSize.QuadPart = Dcb->Header.AllocationSize.QuadPart; } else { #if 0 /* Add MCB entry */ FatAddMcbEntry(Vcb, &Dcb->Mcb, 0, FatRootDirectoryLbo(&Vcb->Bpb), FatRootDirectorySize(&Vcb->Bpb)); /* Set a real size of the root directory */ Dcb->Header.FileSize.QuadPart = FatRootDirectorySize(&Vcb->Bpb); Dcb->Header.AllocationSize.QuadPart = Dcb->Header.FileSize.QuadPart; #endif UNIMPLEMENTED; } }