/// <summary>
 /// to create a WriteMpxSecondary request packet.
 /// </summary>
 /// <param name="uid">This field SHOULD identify the authenticated instance of the user.</param>
 /// <param name="treeId">This field identifies the subdirectory (or tree) on the server that the client is
 /// accessing.</param>
 /// <param name="fid">This field MUST be a valid 16-bit signed integer indicating the file to which the data
 /// should be written.</param>
 /// <param name="byteOffsetToBeginWrite">The requested total number of bytes to write to the file. The value
 /// MAY exceed the negotiated buffer size</param>
 /// <param name="requestMask">This field is a bit mask indicating this SMB request's identity to the
 /// server</param>
 /// <param name="writeMode">A 16-bit field containing flags</param>
 /// <param name="buffer">The raw data in bytes which are to be written to the file.</param>
 /// <returns>a WriteMpxSecondary request packet</returns>
 public SmbWriteMpxSecondaryRequestPacket CreateWriteMpxSecondaryRequest(
     ushort uid,
     ushort treeId,
     ushort fid,
     uint byteOffsetToBeginWrite,
     WriteMpxWriteMode writeMode,
     uint requestMask,
     byte[] buffer)
 {
     return this.CreateWriteMpxSecondaryRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, fid, byteOffsetToBeginWrite,
         writeMode, this.defaultParameters.Timeout, requestMask, buffer);
 }
        /// <summary>
        /// to create a WriteMpxSecondary request packet.
        /// </summary>
        /// <param name="messageId">This field SHOULD be the multiplex ID that is used to associate a response with a
        /// request.</param>
        /// <param name="uid">This field SHOULD identify the authenticated instance of the user.</param>
        /// <param name="treeId">This field identifies the subdirectory (or tree) on the server that the client is
        /// accessing.</param>
        /// <param name="flags">An 8-bit field of 1-bit flags describing various features in effect for the
        /// message</param>
        /// <param name="flags2">A 16-bit field of 1-bit flags that represent various features in effect for the
        /// message. Unspecified bits are reserved and MUST be zero.</param>
        /// <param name="fid">This field MUST be a valid 16-bit signed integer indicating the file to which the data
        /// should be written.</param>
        /// <param name="byteOffsetToBeginWrite">The requested total number of bytes to write to the file. The value
        /// MAY exceed the negotiated buffer size</param>
        /// <param name="requestMask">This field is a bit mask indicating this SMB request's identity to the
        /// server</param>
        /// <param name="timeout">This field MUST be ignored by the server</param>
        /// <param name="writeMode">A 16-bit field containing flags</param>
        /// <param name="buffer">The raw data in bytes which are to be written to the file.</param>
        /// <returns>a WriteMpxSecondary request packet</returns>
        public SmbWriteMpxSecondaryRequestPacket CreateWriteMpxSecondaryRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort fid,
            uint byteOffsetToBeginWrite,
            WriteMpxWriteMode writeMode,
            uint timeout,
            uint requestMask,
            byte[] buffer)
        {
            if (buffer == null)
            {
                buffer = new byte[0];
            }

            SmbWriteMpxSecondaryRequestPacket packet = new SmbWriteMpxSecondaryRequestPacket();

            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_WRITE_MPX_SECONDARY,
                messageId, uid, treeId, flags, flags2);

            SMB_COM_WRITE_MPX_Request_SMB_Parameters smbParameters = new SMB_COM_WRITE_MPX_Request_SMB_Parameters();
            smbParameters.FID = fid;
            smbParameters.TotalByteCount = (ushort)buffer.Length;
            smbParameters.DataLength = (ushort)buffer.Length;
            smbParameters.ByteOffsetToBeginWrite = byteOffsetToBeginWrite;
            smbParameters.Reserved = 0;
            smbParameters.Timeout = timeout;
            smbParameters.WriteMode = writeMode;
            smbParameters.RequestMask = requestMask;
            smbParameters.WordCount = (byte)(Marshal.SizeOf(smbParameters) / NumBytesOfWord);

            SMB_COM_WRITE_MPX_Request_SMB_Data smbData = new SMB_COM_WRITE_MPX_Request_SMB_Data();

            // The size of the preceding SmbParameters part plus Header part is an odd number for all cifs messages
            // If the format is Unicode, needs to add one 16 bits align pad
            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
            {
                // pad 1 byte for 16-bits align:
                smbData.Pad = new byte[1];
            }
            else
            {
                smbData.Pad = new byte[0];
            }
            smbData.Buffer = buffer;
            smbData.ByteCount = (ushort)(smbData.Buffer.Length + smbData.Pad.Length);

            smbParameters.DataOffset = (ushort)(Marshal.SizeOf(packet.SmbHeader) + Marshal.SizeOf(smbParameters)
                + Marshal.SizeOf(smbData.ByteCount) + smbData.Pad.Length);

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;

            return packet;
        }