Esempio n. 1
0
bool GBoneObj::UpdateBuffer()
{
	if (!CombineBuffer(m_dxobj.g_pVertexBuffer.Get(), m_dxobj.g_pIndexBuffer.Get()))
	{
		return false;
	}
	return true;
}
Esempio n. 2
0
FileSystemCode_t
FsWriteToFile(
    _In_  FileSystemDescriptor_t*   FileSystem,
    _In_  MfsEntryHandle_t*         Handle,
    _In_  DmaBuffer_t*              BufferObject,
    _In_  size_t                    Length,
    _Out_ size_t*                   BytesWritten)
{
    MfsInstance_t*   Mfs             = (MfsInstance_t*)FileSystem->ExtensionData;
    MfsEntry_t*      Entry           = (MfsEntry_t*)Handle->Base.Entry;
    FileSystemCode_t Result          = FsOk;
    uint64_t         Position        = Handle->Base.Position;
    size_t           BucketSizeBytes = Mfs->SectorsPerBucket * FileSystem->Disk.Descriptor.SectorSize;
    size_t           BytesToWrite    = Length;

    TRACE("FsWriteEntry(Id 0x%x, Position %u, Length %u)",
        Handle->Base.Id, LODWORD(Position), Length);

    *BytesWritten = 0;
    Result        = MfsEnsureRecordSpace(FileSystem, Entry, Position + BytesToWrite);
    if (Result != FsOk) {
        return Result;
    }

    // Guard against newly allocated files
    if (Handle->DataBucketPosition == MFS_ENDOFCHAIN) {
        Handle->DataBucketPosition  = Entry->StartBucket;
        Handle->DataBucketLength    = Entry->StartLength;
        Handle->BucketByteBoundary  = 0;
    }
    
    // Write in a loop to make sure we write all requested bytes
    while (BytesToWrite) {
        // Calculate which bucket, then the sector offset
        // Then calculate how many sectors of the bucket we need to read
        uint64_t Sector         = MFS_GETSECTOR(Mfs, Handle->DataBucketPosition);
        uint64_t SectorOffset   = (Position - Handle->BucketByteBoundary) % FileSystem->Disk.Descriptor.SectorSize;
        size_t SectorIndex      = (size_t)((Position - Handle->BucketByteBoundary) / FileSystem->Disk.Descriptor.SectorSize);
        size_t SectorsLeft      = MFS_GETSECTOR(Mfs, Handle->DataBucketLength) - SectorIndex;
        size_t SectorCount      = 0, ByteCount = 0;

        // Ok - so sectorindex contains the index in the bucket
        // and sector offset contains the byte-offset in that sector

        // Calculate the sector index into bucket
        Sector += SectorIndex;

        // Calculate how many sectors we should read in
        SectorCount = DIVUP(BytesToWrite, FileSystem->Disk.Descriptor.SectorSize);

        // Do we cross a boundary?
        if (SectorOffset + BytesToWrite > FileSystem->Disk.Descriptor.SectorSize) {
            SectorCount++;
        }

        // Adjust for bucket boundary
        SectorCount = MIN(SectorsLeft, SectorCount);

        // Adjust for number of bytes read
        ByteCount = (size_t)MIN(BytesToWrite, (SectorCount * FileSystem->Disk.Descriptor.SectorSize) - SectorOffset);

        // Ex pos 490 - length 50
        // SectorIndex = 0, SectorOffset = 490, SectorCount = 2 - ByteCount = 50 (Capacity 4096)
        // Ex pos 1109 - length 450
        // SectorIndex = 2, SectorOffset = 85, SectorCount = 2 - ByteCount = 450 (Capacity 4096)
        // Ex pos 490 - length 4000
        // SectorIndex = 0, SectorOffset = 490, SectorCount = 8 - ByteCount = 3606 (Capacity 4096)
        TRACE("Write metrics - Sector %u + %u, Count %u, ByteOffset %u, ByteCount %u",
            LODWORD(Sector), SectorIndex, SectorCount, LODWORD(SectorOffset), ByteCount);

        // First of all, calculate the bounds as we might need to read
        // in existing data - Start out by clearing our combination buffer
        ZeroBuffer(Mfs->TransferBuffer);

        // Case 1 - Handle padding
        if (SectorOffset != 0 || ByteCount != FileSystem->Disk.Descriptor.SectorSize) {
            // Start building the sector
            if (MfsReadSectors(FileSystem, Mfs->TransferBuffer, Sector, 
                SectorCount, &SectorCount) != OsSuccess) {
                ERROR("Failed to read sector %u for combination step", 
                    LODWORD(Sector));
                Result = FsDiskError;
                break;
            }
            
            // Adjust the bytecount if we are not able to read all in one go
            if ((FileSystem->Disk.Descriptor.SectorSize * SectorCount) < ByteCount) {
                ByteCount = FileSystem->Disk.Descriptor.SectorSize * SectorCount;
            }
        }

        // Now write the data to the sector
        SeekBuffer(Mfs->TransferBuffer, (size_t)SectorOffset);
        CombineBuffer(Mfs->TransferBuffer, BufferObject, ByteCount, NULL);

        // Perform the write (Raw - as we need to pass the datapointer)
        if (MfsWriteSectors(FileSystem, Mfs->TransferBuffer, Sector, 
            SectorCount, &SectorCount) != OsSuccess) {
            ERROR("Failed to write sector %u", LODWORD(Sector));
            Result = FsDiskError;
            break;
        }

        // Increase the pointers and decrease with bytes read
        // Adjust the bytecount if we are not able to read all in one go
        if ((FileSystem->Disk.Descriptor.SectorSize * SectorCount) < ByteCount) {
            ByteCount = FileSystem->Disk.Descriptor.SectorSize * SectorCount;
        }
        Position      += ByteCount;
        *BytesWritten += ByteCount;
        BytesToWrite  -= ByteCount;

        // Do we need to switch bucket?
        // We do if the position we have read to equals end of bucket
        if (Position == (Handle->BucketByteBoundary + (Handle->DataBucketLength * BucketSizeBytes))) {
            MapRecord_t Link;

            // We have to lookup the link for current bucket
            if (MfsGetBucketLink(FileSystem, Handle->DataBucketPosition, &Link) != OsSuccess) {
                ERROR("Failed to get link for bucket %u", Handle->DataBucketPosition);
                Result = FsDiskError;
                break;
            }

            // Check for EOL
            if (Link.Link == MFS_ENDOFCHAIN) {
                break;
            }
            Handle->DataBucketPosition = Link.Link;

            // Lookup length of link
            if (MfsGetBucketLink(FileSystem, Handle->DataBucketPosition, &Link) != OsSuccess) {
                ERROR("Failed to get length for bucket %u", Handle->DataBucketPosition);
                Result = FsDiskError;
                break;
            }
            Handle->DataBucketLength    = Link.Length;
            Handle->BucketByteBoundary  += (Link.Length * BucketSizeBytes);
        }
    }

    // entry->modified = now
    Entry->ActionOnClose = MFS_ACTION_UPDATE;
    return Result;
}