public async Task <(NTStatus status, byte[] output)> DeviceIOControl(object handle, uint ctlCode, byte[] input, int maxOutputLength, CancellationToken cancellationToken)
        {
            byte[] output = null;
            if (ctlCode == (uint)IoControlCode.FSCTL_PIPE_WAIT)
            {
                PipeWaitRequest request;
                try
                {
                    request = new PipeWaitRequest(input, 0);
                }
                catch
                {
                    return(NTStatus.STATUS_INVALID_PARAMETER, output);
                }

                RemoteService service = GetService(request.Name);
                if (service == null)
                {
                    return(NTStatus.STATUS_OBJECT_NAME_NOT_FOUND, output);
                }

                output = new byte[0];
                return(NTStatus.STATUS_SUCCESS, output);
            }
            else if (ctlCode == (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE)
            {
                var(writeStatus, numberOfBytesWritten) = await WriteFileAsync(handle, 0, input, cancellationToken);

                if (writeStatus != NTStatus.STATUS_SUCCESS)
                {
                    return(writeStatus, output);
                }
                int messageLength = ((RPCPipeStream)((FileHandle)handle).Stream).MessageLength;

                NTStatus readStatus;
                (readStatus, output) = await ReadFileAsync(handle, 0, maxOutputLength, cancellationToken);

                if (readStatus != NTStatus.STATUS_SUCCESS)
                {
                    return(readStatus, output);
                }

                if (output.Length < messageLength)
                {
                    return(NTStatus.STATUS_BUFFER_OVERFLOW, output);
                }
                else
                {
                    return(NTStatus.STATUS_SUCCESS, output);
                }
            }

            return(NTStatus.STATUS_NOT_SUPPORTED, output);
        }
        public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength)
        {
            output = null;
            if (ctlCode == (uint)IoControlCode.FSCTL_PIPE_WAIT)
            {
                PipeWaitRequest request;
                try
                {
                    request = new PipeWaitRequest(input, 0);
                }
                catch
                {
                    return(NTStatus.STATUS_INVALID_PARAMETER);
                }

                RemoteService service = GetService(request.Name);
                if (service == null)
                {
                    return(NTStatus.STATUS_OBJECT_NAME_NOT_FOUND);
                }

                output = new byte[0];
                return(NTStatus.STATUS_SUCCESS);
            }
            else if (ctlCode == (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE)
            {
                int      numberOfBytesWritten;
                NTStatus writeStatus = WriteFile(out numberOfBytesWritten, handle, 0, input);
                if (writeStatus != NTStatus.STATUS_SUCCESS)
                {
                    return(writeStatus);
                }
                int      messageLength = ((RPCPipeStream)((FileHandle)handle).Stream).MessageLength;
                NTStatus readStatus    = ReadFile(out output, handle, 0, maxOutputLength);
                if (readStatus != NTStatus.STATUS_SUCCESS)
                {
                    return(readStatus);
                }

                if (output.Length < messageLength)
                {
                    return(NTStatus.STATUS_BUFFER_OVERFLOW);
                }
                else
                {
                    return(NTStatus.STATUS_SUCCESS);
                }
            }

            return(NTStatus.STATUS_NOT_SUPPORTED);
        }