/// <summary> /// find the nt transaction packets /// </summary> /// <param name="command">the command of nt transaction</param> /// <param name="setup">the setup contains the sub command</param> /// <returns>the target nt transaction packet</returns> private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup) { SmbPacket smbPacket = null; switch (command) { case NtTransSubCommand.NT_TRANSACT_CREATE: smbPacket = new SmbNtTransactCreateRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_RENAME: smbPacket = new SmbNtTransRenameRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_IOCTL: NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct <NT_TRANSACT_IOCTL_SETUP>(setup); switch ((NtTransFunctionCode)subCommand.FunctionCode) { case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS: smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY: smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK: smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket(); break; default: smbPacket = new SmbNtTransactIoctlRequestPacket(); break; } break; default: switch ((SmbNtTransSubCommand)command) { case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA: smbPacket = new SmbNtTransQueryQuotaRequestPacket(); break; case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA: smbPacket = new SmbNtTransSetQuotaRequestPacket(); break; } break; } return(smbPacket); }
/// <summary> /// Create NTTransIOCtlCopyChunk request for client to copy chunk to server file. /// </summary> /// <param name = "messageId">the id of message, used to identity the request and the server response. </param> /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param> /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param> /// <param name = "flags"> /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. /// </param> /// <param name = "flags2"> /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate /// various client and server capabilities. /// </param> /// <param name = "fileId">the valid file id to operation on, response by server. </param> /// <param name = "isFsctl"> /// This field is TRUE if the command is a file system control command and the FID is a file system control /// device. Otherwise, the command is a device control command and FID is an I/O device. /// </param> /// <param name = "isFlags"> /// If bit 0 is set, the command is to be applied to a share root handle. The share MUST be a Distributed File /// System (DFS) type /// </param> /// <param name = "copychunkResumeKey"> /// A 24-byte resume key generated by the SMB server that can be subsequently used by the client to uniquely /// identify the open source file in a FSCTL_SRV_COPYCHUNK request. /// </param> /// <param name = "list"> /// A concatenated list of copychunk blocks. This field is as specified in section 2.2.14.7.3.1. /// </param> /// <returns>a nt transaction rename request packet </returns> /// <exception cref = "ArgumentNullException">list must not be null </exception> /// <exception cref = "ArgumentException"> /// The number of entries in the copychunk list. MUST NOT be 0. /// </exception> private SmbNtTransFsctlSrvCopyChunkRequestPacket CreateNTTransIOCtlCopyChunkRequest( ushort messageId, ushort sessionUid, ushort treeId, SmbHeader_Flags_Values flags, SmbHeader_Flags2_Values flags2, ushort fileId, bool isFsctl, byte isFlags, byte[] copychunkResumeKey, NT_TRANSACT_COPY_CHUNK_List[] list) { if (list == null) { throw new ArgumentNullException("list"); } if (list.Length == 0) { throw new ArgumentException( "The number of entries in the copychunk list. MUST NOT be 0.", "list"); } SmbNtTransFsctlSrvCopyChunkRequestPacket request = new SmbNtTransFsctlSrvCopyChunkRequestPacket( this.cifsClient.CreateNtTransactIoctlRequest( messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2, this.capability.MaxSetupCount, this.capability.MaxParameterCount, this.capability.MaxDataCount, (uint)NtTransFunctionCode.FSCTL_SRV_COPYCHUNK, fileId, isFsctl, isFlags, null)); // update the copy chunk trans data. NT_TRANSACT_COPY_CHUNK_Request_NT_Trans_Data ntTransData = request.NtTransData; ntTransData.CopyChunkResumeKey = copychunkResumeKey; ntTransData.ChunkCount = (uint)list.Length; ntTransData.List = list; request.NtTransData = ntTransData; request.UpdateCountAndOffset(); return request; }
/// <summary> /// Deep copy constructor. /// </summary> public SmbNtTransFsctlSrvCopyChunkRequestPacket( SmbNtTransFsctlSrvCopyChunkRequestPacket packet) : base(packet) { }
/// <summary> /// NT_TRANSACT_IOCTL Client Request. /// </summary> /// <param name="messageId">Message ID used to identify the message.</param> /// <param name="sessionId">Session ID used to identify the session.</param> /// <param name="treeId">Tree ID used to identify the tree connection.</param> /// <param name="isSigned"> /// Indicate whether the SUT has message signing enabled or required. /// </param> /// <param name="fid">The file identifier.</param> /// <param name="copychunkResumeKeysize">The server resume key for a source file.</param> /// <param name="sourceOffset">The offset in the source file to copy from.</param> /// <param name="targetOffset">The offset in the target file to copy to.</param> /// <param name="length">The number of bytes to copy from the source file to the target file.</param> public void FsctlSrvCopyChunkRequest( int messageId, int sessionId, int treeId, bool isSigned, int fid, string copychunkResumeKeysize, int sourceOffset, int targetOffset, int length) { #region Create Packet SmbNtTransFsctlSrvCopyChunkRequestPacket smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket(); ushort uid = (ushort)this.uId[(uint)sessionId]; byte[] copyChunkResumeKey = null; if (copychunkResumeKeysize == CopyChunkResumeKey) { copyChunkResumeKey = SmbAdapter.resumeKey; } else { copyChunkResumeKey = new byte[24]; for (int i = 0; i < 24; i++) { copyChunkResumeKey[i] = 0x10; } } byte isFlags = byte.MinValue; NT_TRANSACT_COPY_CHUNK_List list = new NT_TRANSACT_COPY_CHUNK_List(); list.Length = (uint)this.copyWordCount; list.SourceOffset = (ulong)sourceOffset; list.DestinationOffset = (ulong)targetOffset; smbPacket = this.smbClientStack.CreateNTTransIOCtlCopyChunkRequest( (ushort)this.fId[(uint)fid], true, isFlags, copyChunkResumeKey, list); if (isSigned) { NamespaceCifs.CifsClientPerConnection connection = this.smbClientStack.Context.GetConnection(ConnectionId); NamespaceCifs.CifsClientPerSession session = this.smbClientStack.Context.GetSession(ConnectionId, uid); smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey); } #endregion #region Send and Receive ExpectPacket this.smbClientStack.SendPacket(smbPacket); StackPacket response = this.smbClientStack.ExpectPacket(this.timeout); NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response; this.QueryUidTable(smbPacketResponse); this.QueryTidTable(smbPacketResponse); VerifyTransport(smbPacketResponse); VerifyCommonMessageSyntax(smbPacketResponse); if (response.GetType() == typeof(SmbErrorResponsePacket)) { SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket; NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader; this.ErrorResponse(smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status); } else { SmbNtTransFsctlSrvCopyChunkResponsePacket smbFsctlSrvCopyChunkPacket = response as SmbNtTransFsctlSrvCopyChunkResponsePacket; NamespaceCifs.SmbHeader ntTransFsctlSrvCopyChunkResponseHeader = smbFsctlSrvCopyChunkPacket.SmbHeader; VerifyMessageSyntaxFsctlSrvCopychunkResponse(smbFsctlSrvCopyChunkPacket); this.FsctlSrvCopyChunkResponse( ntTransFsctlSrvCopyChunkResponseHeader.Mid + this.addMidMark, this.QueryUidTable(smbPacketResponse), this.QueryTidTable(smbPacketResponse), (smbPacketResponse).IsSignRequired, (MessageStatus)ntTransFsctlSrvCopyChunkResponseHeader.Status); } #endregion }
/// <summary> /// find the nt transaction packets /// </summary> /// <param name="command">the command of nt transaction</param> /// <param name="setup">the setup contains the sub command</param> /// <returns>the target nt transaction packet</returns> private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup) { SmbPacket smbPacket = null; switch (command) { case NtTransSubCommand.NT_TRANSACT_CREATE: smbPacket = new SmbNtTransactCreateRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_RENAME: smbPacket = new SmbNtTransRenameRequestPacket(); break; case NtTransSubCommand.NT_TRANSACT_IOCTL: NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct<NT_TRANSACT_IOCTL_SETUP>(setup); switch ((NtTransFunctionCode)subCommand.FunctionCode) { case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS: smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY: smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket(); break; case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK: smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket(); break; default: smbPacket = new SmbNtTransactIoctlRequestPacket(); break; } break; default: switch ((SmbNtTransSubCommand)command) { case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA: smbPacket = new SmbNtTransQueryQuotaRequestPacket(); break; case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA: smbPacket = new SmbNtTransSetQuotaRequestPacket(); break; } break; } return smbPacket; }