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"); }
internal void SetObjectName(MfsObjectHeader* obj, string name) { if (_readOnly) throw new MfsInvalidOperationException(); obj->NameLength = name.Length; Utils.StrCpy(obj->Name, name, 32); }
protected override void DisposeObject(bool disposing) { if (!_fsInternal) { _fs.DereferenceObject(_cellId); _fs.Dereference(disposing); _obj = null; } }
private void InitializeObject(MfsObjectHeader *obj, MfsCellId cellId) { obj->Flink = cellId; obj->Blink = cellId; obj->Parent = MfsCellId.Empty; obj->ChildFlink = cellId; obj->ChildBlink = cellId; obj->DataLength = 0; obj->Data = MfsCellId.Empty; obj->LastData = MfsCellId.Empty; }
internal MemoryObject(MemoryFileSystem fs, MfsCellId cellId, bool fsInternal) { _fs = fs; _cellId = cellId; _obj = _fs.ReferenceObject(cellId); _fsInternal = fsInternal; if (!_fsInternal) _fs.Reference(); // Prevent users from disposing the root object wrapper. if (_fsInternal) this.DisableOwnership(false); }
internal MfsCellId CreateObject(MfsCellId parent, string name) { MfsCellId cellId; MfsObjectHeader *obj; if (_readOnly) { throw new MfsInvalidOperationException(); } obj = (MfsObjectHeader *)this.AllocateCell(out cellId); this.InitializeObject(obj, cellId); this.SetObjectName(obj, name); obj->Parent = parent; MfsObjectHeader *parentObj = this.ReferenceObject(parent); MfsCellId blink; MfsObjectHeader *blinkObj; // Increment the child count. parentObj->ChildCount++; // Insert tail. blink = parentObj->ChildBlink; blinkObj = this.ReferenceObject(blink); obj->Flink = parent; obj->Blink = blink; parentObj->ChildBlink = cellId; // Special case - we are not using linked lists properly, // so we have to use this hack. if (blink == parent) { blinkObj->ChildFlink = cellId; } else { blinkObj->Flink = cellId; } this.DereferenceObject(blink); this.DereferenceObject(parent); this.DereferenceObject(cellId); return(cellId); }
protected override void DisposeObject(bool disposing) { foreach (var vd in _views.Values) { vd.View.Dispose(disposing); } if (_rootObjectMo != null) { _rootObjectMo.Dispose(); } if (_section != null) { _section.Dispose(); } _header = null; _rootObject = null; }
internal MemoryObject(MemoryFileSystem fs, MfsCellId cellId, bool fsInternal) { _fs = fs; _cellId = cellId; _obj = _fs.ReferenceObject(cellId); _fsInternal = fsInternal; if (!_fsInternal) { _fs.Reference(); } // Prevent users from disposing the root object wrapper. if (_fsInternal) { this.DisableOwnership(false); } }
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]; } } }
internal string GetObjectName(MfsObjectHeader *obj) { return(new string(obj->Name, 0, obj->NameLength)); }