public void IoCtl(uint treeId, CtlCode_Values ctlCode, FILEID fileId, IOCTL_Request_Flags_Values flag, out byte[] input, out byte[] output)
        {
            Packet_Header  packetHeader;
            IOCTL_Response response;

            uint status = IoCtl(
                0,
                RequestAndConsumeCredit(),
                signingRequired ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE,
                GetMessageId(),
                sessionId,
                treeId,
                ctlCode,
                fileId,
                0,
                null,
                4096,
                flag,
                out input,
                out output,
                out packetHeader,
                out response
                );

            UpdateCredit(packetHeader);

            if (status != Smb2Status.STATUS_SUCCESS)
            {
                throw new InvalidOperationException(String.Format("IoCtl failed with {0:X08}.", status));
            }
        }
 public bool IsIoCtlCodeSupported(CtlCode_Values ioCtlCode)
 {
     if (UnsupportedIoCtlCodesList == null)
     {
         UnsupportedIoCtlCodesList = ParsePropertyToList <CtlCode_Values>("UnsupportedIoCtlCodes");
     }
     return(!UnsupportedIoCtlCodesList.Contains(ioCtlCode));
 }
Exemple #3
0
        private void SendIoctlPayload(
            Smb2Client client,
            CtlCode_Values code,
            byte[] payload,
            Packet_Header_Flags_Values headerFlags,
            ulong messageId,
            uint treeId,
            ulong sessionId,
            FILEID fileId)
        {
            if (client == null)
            {
                throw new InvalidOperationException("The transport is not connected.");
            }

            if (payload == null)
            {
                throw new ArgumentNullException("payload");
            }

            var request = new Smb2IOCtlRequestPacket();

            request.Header.CreditCharge          = 1;
            request.Header.Command               = Smb2Command.IOCTL;
            request.Header.CreditRequestResponse = 1;
            request.Header.Flags     = headerFlags;
            request.Header.MessageId = messageId;
            request.Header.TreeId    = treeId;
            request.Header.SessionId = sessionId;

            request.PayLoad.CtlCode = code;

            if (code == CtlCode_Values.FSCTL_DFS_GET_REFERRALS || code == CtlCode_Values.FSCTL_DFS_GET_REFERRALS_EX)
            {
                request.PayLoad.FileId = FILEID.Invalid;
            }
            else
            {
                request.PayLoad.FileId = fileId;
            }

            if (payload.Length > 0)
            {
                request.PayLoad.InputOffset = request.BufferOffset;
                request.PayLoad.InputCount  = (ushort)payload.Length;
                request.Buffer = payload;
            }

            request.PayLoad.MaxInputResponse  = 0;
            request.PayLoad.MaxOutputResponse = 4096;
            request.PayLoad.Flags             = IOCTL_Request_Flags_Values.SMB2_0_IOCTL_IS_FSCTL;

            ioctlRequestMessageIds.Enqueue(request.Header.MessageId);
            client.SendPacket(request);
        }
        /// <summary>
        /// Tunnel operations to the shared virtual disk file
        /// </summary>
        /// <typeparam name="ResponseT">Type of the operation response</typeparam>
        /// <param name="isAsyncOperation">Indicate whether the tunnel operation is async or not</param>
        /// <param name="code">Operation code</param>
        /// <param name="requestId">A value that uniquely identifies an operation request and response for all requests sent by this client</param>
        /// <param name="requestStructure">The marshalled tunnel structure of the request</param>
        /// <param name="responseHeader">Tunnel operation header of the response packet</param>
        /// <param name="response">Tunnel operation response of the smb2 response packet</param>
        /// <returns>Status of the smb2 response packet</returns>
        public uint TunnelOperation <ResponseT>(
            bool isAsyncOperation,
            RSVD_TUNNEL_OPERATION_CODE code,
            ulong requestId,
            byte[] requestStructure,
            out SVHDX_TUNNEL_OPERATION_HEADER?responseHeader,
            out ResponseT?response) where ResponseT : struct
        {
            SVHDX_TUNNEL_OPERATION_HEADER header = new SVHDX_TUNNEL_OPERATION_HEADER();

            header.OperationCode = code;
            header.RequestId     = requestId;

            byte[] payload = TypeMarshal.ToBytes(header);

            if (null != requestStructure)
            {
                payload = payload.Concat(requestStructure).ToArray();
            }

            CtlCode_Values ctlCode = isAsyncOperation ? CtlCode_Values.FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST : CtlCode_Values.FSCTL_SVHDX_SYNC_TUNNEL_REQUEST;

            transport.SendIoctlPayload(ctlCode, payload);

            uint smb2Status;

            transport.ExpectIoctlPayload(out smb2Status, out payload);

            response       = null;
            responseHeader = null;
            if (smb2Status != Smb2Status.STATUS_SUCCESS)
            {
                return(smb2Status);
            }

            responseHeader = TypeMarshal.ToStruct <SVHDX_TUNNEL_OPERATION_HEADER>(payload);

            // If the response does not contain Header only, parse the resonse body.
            if (responseHeader.Value.Status == 0 && typeof(ResponseT) != typeof(SVHDX_TUNNEL_OPERATION_HEADER))
            {
                response = TypeMarshal.ToStruct <ResponseT>(payload.Skip(Marshal.SizeOf(responseHeader)).ToArray());
            }
            else
            {
                // The operation failed, so no response body.
                // Or the response only contains header, no response body.
            }

            return(smb2Status);
        }
 /// <summary>
 /// Validate IOCTL and Dialect compatibility
 /// </summary>
 /// <param name="IOCTL">The IOCTL to check against dialect</param>
 public void CheckDialectIOCTLCompatibility(CtlCode_Values IOCTL)
 {
     switch (IOCTL)
     {
     case CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO:
         // FSCTL_VALIDATE_NEGOTIATE_INFO is not supported by SMB311 any more
         if (MaxSmbVersionSupported >= DialectRevision.Smb311 && MaxSmbVersionClientSupported >= DialectRevision.Smb311)
         {
             Site.Assert.Inconclusive("The VALIDATE_NEGOTIATE_INFO request is valid for the client and servers which implement the SMB 3.0 and SMB 3.0.2 dialects");
         }
         break;
         // Add other IOCTL and Dialect compatibility validation if any.
     }
 }
        public void SendIoctlPayload(CtlCode_Values code, byte[] payload)
        {
            if (this.client == null)
            {
                throw new InvalidOperationException("The transport is not connected.");
            }

            if (payload == null)
            {
                throw new ArgumentNullException("payload");
            }

            var request = new Smb2IOCtlRequestPacket();

            request.Header.CreditCharge = IOCTL_DEFAULT_CREDIT_CHARGE;
            request.Header.Command = Smb2Command.IOCTL;
            request.Header.CreditRequestResponse = 1;
            request.Header.Flags = headerFlags;
            request.Header.MessageId = messageId++;
            request.Header.TreeId = treeId;
            request.Header.SessionId = sessionId;

            request.PayLoad.CtlCode = code;

            if (code == CtlCode_Values.FSCTL_DFS_GET_REFERRALS || code == CtlCode_Values.FSCTL_DFS_GET_REFERRALS_EX)
            {
                request.PayLoad.FileId = FILEID.Invalid;
            }
            else
            {
                request.PayLoad.FileId = this.fileId;
            }

            if (payload.Length > 0)
            {
                request.PayLoad.InputOffset = request.BufferOffset;
                request.PayLoad.InputCount = (ushort)payload.Length;
                request.Buffer = payload;
            }

            request.PayLoad.MaxInputResponse = IOCTL_DEFAULT_MAX_INPUT_RESPONSE;
            request.PayLoad.MaxOutputResponse = IOCTL_DEFAULT_MAX_OUTPUT_RESPONSE;
            request.PayLoad.Flags = IOCTL_Request_Flags_Values.SMB2_0_IOCTL_IS_FSCTL;

            ioctlRequestMessageIds.Enqueue(request.Header.MessageId);
            client.SendPacket(request);
        }
 private void AddIoctlCode(CtlCode_Values value, DetectResult result)
 {
     AddResultItem(ref this.ioctlCodesItems, value.ToString(), result);
 }