private void InitializeFs(MfsFsHeader *header, MfsParameters createParams) { header->Magic = MfsMagic; header->NextFreeBlock = 1; if (createParams != null) { // Validate the parameters. this.ValidateFsParameters(createParams.BlockSize, createParams.CellSize); header->BlockSize = createParams.BlockSize; header->CellSize = createParams.CellSize; } else { header->BlockSize = MfsDefaultBlockSize; header->CellSize = MfsDefaultCellSize; } // Store root object in the next cell. MfsObjectHeader *obj = (MfsObjectHeader *)((byte *)header + header->CellSize); this.InitializeObject(obj, _rootObjectCellId); this.SetObjectName(obj, "root"); }
public MemoryFileSystem(string fileName, MfsOpenMode mode, bool readOnly, MfsParameters createParams) { FileCreationDispositionWin32 cdWin32; if (readOnly && mode != MfsOpenMode.Open) { throw new ArgumentException("Invalid mode for read only access."); } switch (mode) { case MfsOpenMode.Open: cdWin32 = FileCreationDispositionWin32.OpenExisting; break; default: case MfsOpenMode.OpenIf: cdWin32 = FileCreationDispositionWin32.OpenAlways; break; case MfsOpenMode.OverwriteIf: cdWin32 = FileCreationDispositionWin32.CreateAlways; break; } using (var fhandle = FileHandle.CreateWin32( fileName, FileAccess.GenericRead | (!readOnly ? FileAccess.GenericWrite : 0), FileShareMode.Read, cdWin32 )) { bool justCreated = false; _readOnly = readOnly; _protection = !readOnly ? MemoryProtection.ReadWrite : MemoryProtection.ReadOnly; if (fhandle.GetSize() == 0) { if (readOnly) { throw new MfsInvalidFileSystemException(); } else { // File is too small. Make it 1 byte large and we'll deal with it // soon. fhandle.SetEnd(1); } } _section = new Section(fhandle, _protection); _blockSize = MfsBlockSizeBase; // fake block size to begin with; we'll fix it up later. if (fhandle.GetSize() < _blockSize) { if (readOnly) { throw new MfsInvalidFileSystemException(); } else { // We're creating a new file system. We need the correct block size // now. if (createParams != null) { _blockSize = createParams.BlockSize; } else { _blockSize = MfsDefaultBlockSize; } _section.Extend(_blockSize); using (var view = _section.MapView(0, _blockSize, _protection)) this.InitializeFs((MfsFsHeader *)view.Memory, createParams); justCreated = true; } } _header = (MfsFsHeader *)this.ReferenceBlock(0); // Check the magic. if (_header->Magic != MfsMagic) { throw new MfsInvalidFileSystemException(); } // Set up the local constants. _blockSize = _header->BlockSize; _cellSize = _header->CellSize; // Backwards compatibility. if (_blockSize == 0) { _blockSize = MfsDefaultBlockSize; } if (_cellSize == 0) { _cellSize = MfsDefaultCellSize; } // Validate the parameters. this.ValidateFsParameters(_blockSize, _cellSize); _blockMask = _blockSize - 1; _cellCount = _blockSize / _cellSize; _dataCellDataMaxLength = _cellSize - MfsDataCell.DataOffset; // Remap block 0 with the correct block size. this.DereferenceBlock(0); // If we just created a new file system, fix the section size. if (justCreated) { _section.Extend(_blockSize); } _header = (MfsFsHeader *)this.ReferenceBlock(0); // Set up the root object. _rootObject = (MfsObjectHeader *)((byte *)_header + _cellSize); _rootObjectMo = new MemoryObject(this, _rootObjectCellId, true); if (_header->NextFreeBlock != 1 && !readOnly) { ushort lastBlockId = (ushort)(_header->NextFreeBlock - 1); this.ReferenceBlock(lastBlockId); _cachedLastBlockView = _views[lastBlockId]; } } }