public static async Task FileZeroClearAsync(SafeFileHandle handle, string pathForReference, long offset, long size, CancellationToken cancel = default)
        {
            if (Env.IsWindows == false)
            {
                throw new PlatformNotSupportedException();
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (size < 0)
            {
                throw new ArgumentOutOfRangeException("size");
            }
            if (size == 0)
            {
                return;
            }

            Win32Api.Kernel32.FILE_ZERO_DATA_INFORMATION data = new Win32Api.Kernel32.FILE_ZERO_DATA_INFORMATION(offset, size);
            ReadOnlyMemoryBuffer <byte> inBuffer = ReadOnlyMemoryBuffer <byte> .FromStruct(data);

            await Win32Api.Kernel32.DeviceIoControlAsync(handle, Win32Api.Kernel32.EIOControlCode.FsctlSetZeroData, inBuffer, null, pathForReference, cancel);
        }
        public static async Task SetCompressionFlagAsync(SafeFileHandle handle, bool compressionEnabled, string?pathForReference = null, CancellationToken cancel = default)
        {
            if (Env.IsWindows == false)
            {
                return;
            }

            ushort inFlag = (ushort)(compressionEnabled ? Win32Api.Kernel32.COMPRESSION_FORMAT_DEFAULT : Win32Api.Kernel32.COMPRESSION_FORMAT_NONE);

            var bufferIn = ReadOnlyMemoryBuffer <byte> .FromStruct(inFlag);

            var bufferOut = new MemoryBuffer <byte>();

            await Win32Api.Kernel32.DeviceIoControlAsync(handle, Win32Api.Kernel32.EIOControlCode.FsctlSetCompression, bufferIn, bufferOut, pathForReference, cancel);
        }
示例#3
0
        async Task ServerMainLoop(CancellationToken mainLoopCancel)
        {
            if (Once.IsFirstCall() == false)
            {
                throw new ApplicationException("You cannot reuse the object.");
            }

            using (var sessions = new GroupManager <ulong, SessionData>(
                       onNewGroup: (key, state) =>
            {
                Dbg.Where($"New session: {key}");
                return(new SessionData());
            },
                       onDeleteGroup: (key, ctx, state) =>
            {
                Dbg.Where($"Delete session: {key}");
            }))
            {
                var listener = System.CreateListener(new TcpListenParam(async(lx, sock) =>
                {
                    Con.WriteLine($"Connected {sock.Info.Tcp.RemoteIPAddress}:{sock.Info.Tcp.RemotePort} -> {sock.Info.Tcp.LocalIPAddress}:{sock.Info.Tcp.LocalPort}");

                    var app = sock.GetNetAppProtocolStub();

                    var st = app.GetStream();

                    var attachHandle = app.AttachHandle;

                    attachHandle.SetStreamReceiveTimeout(RecvTimeout);

                    await st.SendAsync("TrafficServer\r\n\0"._GetBytes_Ascii());

                    ReadOnlyMemoryBuffer <byte> buf = await st.ReceiveAsync(17);

                    Direction dir   = buf.ReadBool8() ? Direction.Send : Direction.Recv;
                    ulong sessionId = 0;
                    long timespan   = 0;

                    try
                    {
                        sessionId = buf.ReadUInt64();
                        timespan  = buf.ReadSInt64();
                    }
                    catch { }

                    long recvEndTick = FastTick64.Now + timespan;
                    if (timespan == 0)
                    {
                        recvEndTick = long.MaxValue;
                    }

                    using (var session = sessions.Enter(sessionId))
                    {
                        using (var delay = new DelayAction((int)(Math.Min(timespan * 3 + 180 * 1000, int.MaxValue)), x => app._CancelSafe(new TimeoutException())))
                        {
                            if (dir == Direction.Recv)
                            {
                                RefInt refTmp  = new RefInt();
                                long totalSize = 0;

                                while (true)
                                {
                                    var ret = await st.FastReceiveAsync(totalRecvSize: refTmp);
                                    if (ret.Count == 0)
                                    {
                                        break;
                                    }
                                    totalSize += refTmp;

                                    if (ret[0].Span[0] == (byte)'!')
                                    {
                                        break;
                                    }

                                    if (FastTick64.Now >= recvEndTick)
                                    {
                                        break;
                                    }
                                }

                                attachHandle.SetStreamReceiveTimeout(Timeout.Infinite);
                                attachHandle.SetStreamSendTimeout(60 * 5 * 1000);

                                session.Context.NoMoreData = true;

                                while (true)
                                {
                                    MemoryBuffer <byte> sendBuf = new MemoryBuffer <byte>();
                                    sendBuf.WriteSInt64(totalSize);

                                    await st.SendAsync(sendBuf);

                                    await Task.Delay(100);
                                }
                            }
                            else
                            {
                                attachHandle.SetStreamReceiveTimeout(Timeout.Infinite);
                                attachHandle.SetStreamSendTimeout(Timeout.Infinite);

                                while (true)
                                {
                                    if (sessionId == 0 || session.Context.NoMoreData == false)
                                    {
                                        await st.SendAsync(SendData);
                                    }
                                    else
                                    {
                                        var recvMemory = await st.ReceiveAsync();

                                        if (recvMemory.Length == 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                                                                        "SpeedTest",
                                                                        this.ServerPorts));

                try
                {
                    Con.WriteLine("Listening.");

                    await TaskUtil.WaitObjectsAsync(cancels : mainLoopCancel._SingleArray());
                }
                finally
                {
                    await listener._DisposeWithCleanupSafeAsync();
                }
            }
        }