예제 #1
0
        public override int Write(object fileNode,
                                  object fileDesc,
                                  IntPtr buffer,
                                  ulong offset,
                                  uint length,
                                  bool writeToEndOfFile,
                                  bool constrainedIo,
                                  out uint bytesTransferred,
                                  out FileInfo fileInfo)
        {
            if (fileNode is FileNode node &&
                fileDesc is FileMetadata metadata)
            {
                Logger.LogTrace(
                    $"Request {nameof ( Write )} to \"{metadata . Name}\", start from {offset} with length {length}({( ( long ) length ) . BytesCountToHumanString ( )}).");

                if (writeToEndOfFile)
                {
                    offset = ( ulong )metadata.Size;
                }

                if (!constrainedIo)
                {
                    ResizeFile(
                        node,
                        Math.Max(metadata.Size, ( long )offset + length));
                    length = ( uint )Math.Min(metadata.Size - ( long )offset, length);
                }

                int startBlockSequence = ( int )(offset / ( ulong )BlockSize);

                int endBlockSequence =
                    ( int )((offset + length + ( ulong )BlockSize - 1)
                            / ( ulong )BlockSize);

                int currentByteSequence = 0;

                int currentBlockSequence = startBlockSequence;

                CachedBlock currentBlock = node.GetBlock(currentBlockSequence);

                #region firstBlock

                int firstByteStartFrom = ( int )(offset % ( ulong )BlockSize);

                int currentBlockCopyByteCount = ( int )Math.Min(
                    BlockSize - firstByteStartFrom,
                    length
                    - currentByteSequence);

                currentBlock.IsModified = true;

                Marshal.Copy(
                    buffer + currentByteSequence,
                    currentBlock.Content,
                    firstByteStartFrom,
                    currentBlockCopyByteCount);

                currentByteSequence += currentBlockCopyByteCount;

                currentBlockSequence++;

                #endregion

                firstByteStartFrom = 0;

                for ( ; currentBlockSequence < endBlockSequence; currentBlockSequence++)
                {
                    currentBlock = node.GetBlock(currentBlockSequence);

                    currentBlockCopyByteCount = ( int )Math.Min(
                        BlockSize - firstByteStartFrom,
                        length
                        - currentByteSequence);


                    currentBlock.IsModified = true;

                    Marshal.Copy(
                        buffer + currentByteSequence,
                        currentBlock.Content,
                        firstByteStartFrom,
                        currentBlockCopyByteCount);

                    currentByteSequence += currentBlockCopyByteCount;
                }

                bytesTransferred = ( uint )currentByteSequence;

                fileInfo = metadata.FileInfo;

                Logger.LogDebug(
                    $"Written to \"{metadata . Name}\", start from {offset} with length {bytesTransferred}({( ( long ) bytesTransferred ) . BytesCountToHumanString ( )}).");

                return(STATUS_SUCCESS);
            }

            throw GetIoExceptionWithNtStatus(STATUS_INVALID_HANDLE);
        }
예제 #2
0
        public override int Read(object fileNode,
                                 object fileDesc,
                                 IntPtr buffer,
                                 ulong offset,
                                 uint length,
                                 out uint bytesTransferred)
        {
            if (fileNode is FileNode node &&
                fileDesc is FileMetadata metadata)
            {
                Logger.LogTrace(
                    $"Request {nameof ( Read )} from \"{metadata . Name}\", start from {offset} with length {length}({( ( long ) length ) . BytesCountToHumanString ( )}).");

                if (offset >= ( ulong )metadata.Size)
                {
                    bytesTransferred = default;
                    return(STATUS_END_OF_FILE);
                }

                length = ( uint )Math.Min(length, metadata.Size - ( long )offset);

                int startBlockSequence = ( int )(offset / ( ulong )BlockSize);

                int endBlockSequence =
                    ( int )((offset + length + ( ulong )BlockSize - 1)
                            / ( ulong )BlockSize);

                endBlockSequence = Math.Min(
                    endBlockSequence,
                    metadata.AllocatedBlockCount - 1);

                int currentByteSequence = 0;

                int currentBlockSequence = startBlockSequence;

                #region firstBlock

                CachedBlock currentBlock = node.GetBlock(currentBlockSequence);

                int firstByteStartFrom = ( int )(offset % ( ulong )BlockSize);

                int currentBlockCopyByteCount = ( int )Math.Min(
                    BlockSize - firstByteStartFrom,
                    length
                    - currentByteSequence);

                Marshal.Copy(
                    currentBlock.Content,
                    firstByteStartFrom,
                    buffer + currentByteSequence,
                    currentBlockCopyByteCount);

                currentByteSequence += currentBlockCopyByteCount;

                currentBlockSequence++;

                #endregion

                firstByteStartFrom = 0;

                for ( ; currentBlockSequence < endBlockSequence; currentBlockSequence++)
                {
                    currentBlock = node.GetBlock(currentBlockSequence);


                    currentBlockCopyByteCount = ( int )Math.Min(
                        BlockSize - firstByteStartFrom,
                        length
                        - currentByteSequence);

                    Marshal.Copy(
                        currentBlock.Content,
                        firstByteStartFrom,
                        buffer + currentByteSequence,
                        currentBlockCopyByteCount);

                    currentByteSequence += currentBlockCopyByteCount;
                }

                bytesTransferred = ( uint )currentByteSequence;

                Logger.LogDebug(
                    $"Read from \"{metadata . Name}\", start from {offset} with length {bytesTransferred}({( ( long ) bytesTransferred ) . BytesCountToHumanString ( )}).");

                return(STATUS_SUCCESS);
            }

            throw GetIoExceptionWithNtStatus(STATUS_INVALID_HANDLE);
        }