/// <summary>
 /// to create a Trans2FindFirst2 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="extendedAttributeList">A list of extended file attribute name/value pairs. </param>
 /// <param name="searchCount">The server MUST NOT return more entries than indicated by the value of this
 /// field.</param>
 /// <param name="searchAttributes">File attributes to apply as a constraint to the file search.</param>
 /// <param name="findFlags">This 16-bit field of flags is used to request that the server take
 /// certain actions.</param>
 /// <param name="informationLevel">This field contains an information level code, which determines the
 /// information contained in the response.</param>
 /// <param name="searchStorageType">This field specifies if the find is searching for directories or for files.
 /// This field MUST be one of two values</param>
 /// <param name="name">A buffer containing the name of the file to be opened, created, or truncated. The
 /// string MUST be null terminated</param>
 /// <returns>a Trans2FindFirst2 request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbTrans2FindFirst2RequestPacket CreateTrans2FindFirst2Request(
     ushort uid,
     ushort treeId,
     SmbFileAttributes searchAttributes,
     Trans2FindFlags findFlags,
     ushort searchCount,
     FindInformationLevel informationLevel,
     Trans2FindFirst2SearchStorageType searchStorageType,
     string name,
     SMB_GEA[] extendedAttributeList)
 {
     return this.CreateTrans2FindFirst2Request(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, this.defaultParameters.MaxParameterCount,
         this.defaultParameters.MaxDataCount, this.defaultParameters.MaxSetupCount, this.defaultParameters.Trans2SmbParametersFlags,
         this.defaultParameters.Timeout, searchAttributes, searchCount, findFlags, informationLevel,
         searchStorageType, name, extendedAttributeList);
 }
        /// <summary>
        /// to create a Trans2Open2 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="maxParameterCount">The maximum number of parameter bytes that the client will accept in the
        /// transaction reply. The server MUST NOT return more than this number of parameter bytes.</param>
        /// <param name="maxDataCount">The maximum number of data bytes that the client will accept in the transaction
        /// reply. The server MUST NOT return more than this number of data bytes.</param>
        /// <param name="maxSetupCount">Maximum number of setup bytes that the client will accept in the transaction
        /// reply. The server MUST NOT return more than this number of setup bytes</param>
        /// <param name="smbParametersFlags">A set of bit flags that alter the behavior of the requested operation.
        /// Unused bit fields MUST be set to zero by the client sending the request, and MUST be ignored by the server
        /// receiving the request. The client MAY set either or both of the following bit flags</param>
        /// <param name="timeout">The number of milliseconds the server SHOULD wait for completion of the transaction
        /// before generating a timeout. A value of zero indicates that the operation MUST NOT block.</param>
        /// <param name="allocationSize">The number of bytes to reserve for the file if the file is being created or
        /// truncated. </param>
        /// <param name="creationTimeInSeconds">A time value expressed in seconds past Jan 1, 1970 00:00:00:00 to apply
        /// to the file's attributes if the file is created</param>
        /// <param name="desiredAccess">A 16-bit field for encoding the requested access mode. See section 3.2.4.5.1
        /// for a discussion on sharing modes</param>
        /// <param name="extendedAttributeList">A list of extended file attribute name / value pairs that are to be
        /// assigned to the file.</param>
        /// <param name="fileAttributes">Attributes to apply to the file if it needs to be created.</param>
        /// <param name="name">A buffer containing the name of the file to be opened, created, or truncated. The
        /// string MUST be null terminated</param>
        /// <param name="open2Flags">This 16-bit field of flags is used to request that the server take certain
        /// actions.</param>
        /// <param name="openMode">A 16-bit field that controls the way a file SHOULD be treated when it is opened for
        /// use by certain extended SMB requests</param>
        /// <returns>a Trans2Open2 request packet</returns>
        public SmbTrans2Open2RequestPacket CreateTrans2Open2Request(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            Trans2Open2Flags open2Flags,
            Trans2Open2DesiredAccess desiredAccess,
            SmbFileAttributes fileAttributes,
            uint creationTimeInSeconds,
            OpenMode openMode,
            uint allocationSize,
            string name,
            SMB_FEA[] extendedAttributeList)
        {
            if (name == null)
            {
                name = string.Empty;
            }
            if (extendedAttributeList == null)
            {
                extendedAttributeList = new SMB_FEA[0];
            }

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

            // Set Smb_Parameters
            SMB_COM_TRANSACTION2_Request_SMB_Parameters smbParameters =
                new SMB_COM_TRANSACTION2_Request_SMB_Parameters();
            smbParameters.MaxParameterCount = maxParameterCount;
            smbParameters.MaxDataCount = maxDataCount;
            smbParameters.MaxSetupCount = maxSetupCount;
            smbParameters.Flags = (ushort)smbParametersFlags;
            smbParameters.Timeout = timeout;
            smbParameters.SetupCount = 1; // the correct count in word of the Setup is always 1.
            smbParameters.Setup = new ushort[] { (ushort)Trans2SubCommand.TRANS2_OPEN2 };
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_TRANSACTION2_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            // Set Smb_Data
            SMB_COM_TRANSACTION2_Request_SMB_Data smbData = new SMB_COM_TRANSACTION2_Request_SMB_Data();
            smbData.Name = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // The size of the preceding SmbParameters part plus Header part is an odd number for all cifs messages
            // Use Name field to judge whether needs to add one 16-bits align pad.
            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE && smbData.Name.Length
                % twoBytesAlign == 0)
            {
                // pad 1 byte for 16-bits align:
                smbData.Pad1 = new byte[1];
            }
            else
            {
                smbData.Pad1 = new byte[0];
            }

            // Set Trans2_Parameters
            TRANS2_OPEN2_Request_Trans2_Parameters trans2Parameters = new TRANS2_OPEN2_Request_Trans2_Parameters();
            trans2Parameters.Flags = (ushort)open2Flags;
            trans2Parameters.AccessMode = (ushort)desiredAccess;
            trans2Parameters.FileAttributes = fileAttributes;
            trans2Parameters.CreationTime = creationTimeInSeconds;
            trans2Parameters.OpenMode = (ushort)openMode;
            trans2Parameters.AllocationSize = allocationSize;
            trans2Parameters.Reserved = new ushort[5]; // the correct length of Reserved word is always 5.
            trans2Parameters.FileName = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // Set Trans2_Data
            TRANS2_OPEN2_Request_Trans2_Data trans2Data = new TRANS2_OPEN2_Request_Trans2_Data();
            trans2Data.ExtendedAttributeList.FEAList = extendedAttributeList;
            trans2Data.ExtendedAttributeList.SizeOfListInBytes =
                (uint)CifsMessageUtils.GetSize<uint>(trans2Data.ExtendedAttributeList.SizeOfListInBytes);
            trans2Data.ExtendedAttributeList.SizeOfListInBytes +=
                CifsMessageUtils.GetSmbEAListSize(extendedAttributeList);

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.Trans2Parameters = trans2Parameters;
            packet.Trans2Data = trans2Data;
            packet.UpdateCountAndOffset();

            return packet;
        }
        public SmbQueryInformationResponsePacket CreateQueryInformationResponse(
            CifsServerPerConnection connection,
            SmbQueryInformationRequestPacket request,
            SmbFileAttributes fileAttributes,
            UTime lastWriteTime,
            uint fileSize)
        {
            SmbQueryInformationResponsePacket response = new SmbQueryInformationResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            SMB_COM_QUERY_INFORMATION_Response_SMB_Parameters smbParameters = response.SmbParameters;
            smbParameters.FileAttributes = fileAttributes;
            smbParameters.FileSize = fileSize;
            smbParameters.LastWriteTime = lastWriteTime;
            smbParameters.Reserved = new ushort[5];
            smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2);
            response.SmbParameters = smbParameters;

            return response;
        }
        /// <summary>
        /// to create a Trans2FindFirst2 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="maxParameterCount">The maximum number of parameter bytes that the client will accept in the
        /// transaction reply. The server MUST NOT return more than this number of parameter bytes.</param>
        /// <param name="maxDataCount">The maximum number of data bytes that the client will accept in the transaction
        /// reply. The server MUST NOT return more than this number of data bytes.</param>
        /// <param name="maxSetupCount">Maximum number of setup bytes that the client will accept in the transaction
        /// reply. The server MUST NOT return more than this number of setup bytes</param>
        /// <param name="smbParametersFlags">A set of bit flags that alter the behavior of the requested operation.
        /// Unused bit fields MUST be set to zero by the client sending the request, and MUST be ignored by the server
        /// receiving the request. The client MAY set either or both of the following bit flags</param>
        /// <param name="timeout">The number of milliseconds the server SHOULD wait for completion of the transaction
        /// before generating a timeout. A value of zero indicates that the operation MUST NOT block.</param>
        /// <param name="extendedAttributeList">A list of extended file attribute name/value pairs. </param>
        /// <param name="searchCount">The server MUST NOT return more entries than indicated by the value of this
        /// field.</param>
        /// <param name="searchAttributes">File attributes to apply as a constraint to the file search.</param>
        /// <param name="informationLevel">This field contains an information level code, which determines the
        /// information contained in the response.</param>
        /// <param name="searchStorageType">This field specifies if the find is searching for directories or for files.
        /// This field MUST be one of two values</param>
        /// <param name="name">A buffer containing the name of the file to be opened, created, or truncated. The
        /// string MUST be null terminated</param>
        /// <param name="findFlags">This 16-bit field of flags is used to request that the server take
        /// certain actions.</param>
        /// <returns>a Trans2FindFirst2 request packet</returns>
        public SmbTrans2FindFirst2RequestPacket CreateTrans2FindFirst2Request(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxParameterCount,
            ushort maxDataCount,
            byte maxSetupCount,
            Trans2SmbParametersFlags smbParametersFlags,
            uint timeout,
            SmbFileAttributes searchAttributes,
            ushort searchCount,
            Trans2FindFlags findFlags,
            FindInformationLevel informationLevel,
            Trans2FindFirst2SearchStorageType searchStorageType,
            string name,
            SMB_GEA[] extendedAttributeList)
        {
            if (name == null)
            {
                name = string.Empty;
            }
            if (extendedAttributeList == null)
            {
                extendedAttributeList = new SMB_GEA[0];
            }

            SmbTrans2FindFirst2RequestPacket packet = new SmbTrans2FindFirst2RequestPacket();

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

            // Set Smb_Parameters
            SMB_COM_TRANSACTION2_Request_SMB_Parameters smbParameters =
                new SMB_COM_TRANSACTION2_Request_SMB_Parameters();
            smbParameters.MaxParameterCount = maxParameterCount;
            smbParameters.MaxDataCount = maxDataCount;
            smbParameters.MaxSetupCount = maxSetupCount;
            smbParameters.Flags = (ushort)smbParametersFlags;
            smbParameters.Timeout = timeout;
            smbParameters.SetupCount = 1; // the correct count in word of the Setup is always 1.
            smbParameters.Setup = new ushort[] { (ushort)Trans2SubCommand.TRANS2_FIND_FIRST2 };
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_TRANSACTION2_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            // Set Smb_Data
            SMB_COM_TRANSACTION2_Request_SMB_Data smbData = new SMB_COM_TRANSACTION2_Request_SMB_Data();
            smbData.Name = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // The size of the preceding SmbParameters part plus Header part is an odd number for all cifs messages
            // Use Name field to judge whether needs to add one 16-bits align pad.
            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE && smbData.Name.Length
                % twoBytesAlign == 0)
            {
                // pad 1 byte for 16-bits align:
                smbData.Pad1 = new byte[1];
            }
            else
            {
                smbData.Pad1 = new byte[0];
            }

            // Set Trans2_Parameters
            TRANS2_FIND_FIRST2_Request_Trans2_Parameters trans2Parameters =
                new TRANS2_FIND_FIRST2_Request_Trans2_Parameters();
            trans2Parameters.SearchAttributes = searchAttributes;
            trans2Parameters.SearchCount = searchCount;
            trans2Parameters.Flags = findFlags;
            trans2Parameters.InformationLevel = informationLevel;
            trans2Parameters.SearchStorageType = searchStorageType;
            trans2Parameters.FileName = CifsMessageUtils.ToSmbStringBytes(name,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);

            // Set Trans2_Data
            TRANS2_FIND_FIRST2_Request_Trans2_Data trans2Data = new TRANS2_FIND_FIRST2_Request_Trans2_Data();
            trans2Data.GetExtendedAttributeList.GEAList = extendedAttributeList;
            trans2Data.GetExtendedAttributeList.SizeOfListInBytes =
                (uint)CifsMessageUtils.GetSize<uint>(trans2Data.GetExtendedAttributeList.SizeOfListInBytes);
            trans2Data.GetExtendedAttributeList.SizeOfListInBytes +=
                CifsMessageUtils.GetSmbQueryEAListSize(extendedAttributeList);

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.Trans2Parameters = trans2Parameters;
            packet.Trans2Data = trans2Data;
            packet.UpdateCountAndOffset();

            return packet;
        }
 /// <summary>
 /// Create a open request packet for client to open a share on server. 
 /// </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 = "shareName">the file name to open </param>
 /// <param name = "fileOpenMode">file open mode </param>
 /// <param name = "fileOpenFunction">
 /// A 16-bit field that controls the way a file SHOULD be treated when it is opened for use by certain 
 /// extended SMB requests. 
 /// </param>
 /// <param name = "extFileAttributes">the extend file attributes </param>
 /// <param name = "extSearchAttributes">the search attributes of file </param>
 /// <param name = "allocationSize">Bytes to reserve on create or truncate </param>
 /// <param name = "openFlags">A 16-bit field of flags for requesting attribute data and locking </param>
 /// <returns>a open request packet </returns>
 private SmbOpenAndxRequestPacket CreateOpenRequest(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     string shareName,
     AccessMode fileOpenMode,
     OpenMode fileOpenFunction,
     SmbFileAttributes extFileAttributes,
     SmbFileAttributes extSearchAttributes,
     uint allocationSize,
     OpenFlags openFlags)
 {
     return new SmbOpenAndxRequestPacket(
         this.cifsClient.CreateOpenAndxRequest(messageId, sessionUid, treeId,
         (SmbFlags)flags, (SmbFlags2)flags2, (Flags)openFlags, fileOpenMode,
         extSearchAttributes, extFileAttributes, new UTime(), fileOpenFunction,
         allocationSize, this.capability.Timeout, shareName, null));
 }
 /// <summary>
 /// Create a open request packet for client to open a share on server. 
 /// </summary>
 /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
 /// <param name = "shareName">the file name to open </param>
 /// <param name = "fileOpenMode">file open mode </param>
 /// <param name = "fileOpenFunction">
 /// A 16-bit field that controls the way a file SHOULD be treated when it is opened for use by certain 
 /// extended SMB requests. 
 /// </param>
 /// <param name = "extFileAttributes">the extend file attributes </param>
 /// <returns>a open request packet </returns>
 public virtual SmbOpenAndxRequestPacket CreateOpenRequest(
     ushort treeId,
     string shareName,
     AccessMode fileOpenMode,
     OpenMode fileOpenFunction,
     SmbFileAttributes extFileAttributes)
 {
     return CreateOpenRequest(
         this.MessageId, this.GetSessionIdByTreeId(treeId), treeId,
        this.capability.Flag, this.capability.Flags2,
         shareName, fileOpenMode, fileOpenFunction, extFileAttributes,
         SmbFileAttributes.SMB_FILE_ATTRIBUTE_ARCHIVE | SmbFileAttributes.SMB_FILE_ATTRIBUTE_DIRECTORY
         | SmbFileAttributes.SMB_FILE_ATTRIBUTE_HIDDEN | SmbFileAttributes.SMB_FILE_ATTRIBUTE_NORMAL
         | SmbFileAttributes.SMB_FILE_ATTRIBUTE_READONLY | SmbFileAttributes.SMB_FILE_ATTRIBUTE_SYSTEM
         | SmbFileAttributes.SMB_FILE_ATTRIBUTE_VOLUME,
         0x00, OpenFlags.SMB_OPEN_EXTENDED_RESPONSE);
 }
        /// <summary>
        /// to create a Rename 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="searchAttributes">The file attributes of the file(s) to be deleted. If the value of this
        /// field is zero, then only normal files MUST be matched for deletion.  If the System or Hidden attributes
        /// MUST be specified, then entries with those attributes are matched in addition to the normal files. 
        /// Read-only files MAY NOT be deleted. The read-only attribute of the file MUST be cleared before the file
        /// MAY be deleted.</param>
        /// <param name="oldFileName">A null-terminated string containing the name of the file or files to be renamed.
        /// Wildcards MAY be used in the filename component of the path</param>
        /// <param name="newFileName">A null-terminated string containing the new name(s) to be given to the file(s)
        /// that matches OldFileName or the name of the destination directory into which the files matching 
        /// OldFileName MUST be moved.</param>
        /// <returns>a Rename request packet</returns>
        public SmbRenameRequestPacket CreateRenameRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            SmbFileAttributes searchAttributes,
            string oldFileName,
            string newFileName)
        {
            if (oldFileName == null)
            {
                oldFileName = string.Empty;
            }
            if (newFileName == null)
            {
                newFileName = string.Empty;
            }

            SmbRenameRequestPacket packet = new SmbRenameRequestPacket();

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

            SMB_COM_RENAME_Request_SMB_Parameters smbParameters = new SMB_COM_RENAME_Request_SMB_Parameters();
            smbParameters.SearchAttributes = searchAttributes;
            smbParameters.WordCount = (byte)(Marshal.SizeOf(smbParameters) / NumBytesOfWord);

            SMB_COM_RENAME_Request_SMB_Data smbData = new SMB_COM_RENAME_Request_SMB_Data();
            smbData.BufferFormat1 = (byte)DataBufferFormat.SmbString;
            smbData.OldFileName = CifsMessageUtils.ToSmbStringBytes(oldFileName,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);
            smbData.BufferFormat2 = (byte)DataBufferFormat.SmbString;

            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
            {
                // if Unicode, add 1 byte pad for align on 16-bits.
                smbData.NewFileName = new byte[1 + (newFileName.Length + 1) * 2];
                Array.Copy(CifsMessageUtils.ToSmbStringBytes(newFileName, true), 0, smbData.NewFileName, 1,
                    (newFileName.Length + 1) * 2);
            }
            else
            {
                smbData.NewFileName = CifsMessageUtils.ToSmbStringBytes(newFileName, false);
            }
            smbData.ByteCount = (ushort)(Marshal.SizeOf(smbData.BufferFormat1) + smbData.OldFileName.Length
                + Marshal.SizeOf(smbData.BufferFormat2) + smbData.NewFileName.Length);

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

            return packet;
        }
 /// <summary>
 /// to create a Create 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="fileAttributes">A 16-bit field of 1-bit flags that represent the file attributes to assign to
 /// the file if it is created successfully.</param>
 /// <param name="creationTime">UTIME The time the file was created on the client represented as the number of
 /// seconds since Jan 1, 1970, 00:00:00.0. Server support of this field is OPTIONAL</param>
 /// <param name="fileName">A null-terminated string that represents the fully qualified name of the file
 /// relative to the supplied TID to create or truncate on the server.</param>
 /// <returns>a Create Request Packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbCreateRequestPacket CreateCreateRequest(
     ushort uid,
     ushort treeId,
     SmbFileAttributes fileAttributes,
     UTime creationTime,
     string fileName)
 {
     return this.CreateCreateRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, fileAttributes, creationTime, fileName);
 }
 /// <summary>
 /// to create a OpenAndx 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="smbParametersFlags">A 16-bit field of flags for requesting attribute data and locking</param>
 /// <param name="accessMode">A 16-bit field for encoding the requested access mode. See section 3.2.4.5.1 for a
 /// discussion on sharing modes</param>
 /// <param name="searchAttrs">ATTRIBUTES The set of attributes that the file MUST have in order to be found
 /// while searching to see if it exists. If none of the attribute bytes are set, the file attributes MUST refer
 /// to a regular file.</param>
 /// <param name="fileAttrs">The set of attributes that the file is to have if the file needs to be created. If
 /// none of the attribute bytes are set, the file attributes MUST refer to a regular file.</param>
 /// <param name="creationTime">32-bit integer time value to be assigned to the file as a time of creation if
 /// the file is to be created. </param>
 /// <param name="openMode">A 16-bit field that controls the way a file SHOULD be treated when it is opened for
 /// use by certain extended SMB requests</param>
 /// <param name="allocationSize">The number of bytes to reserve on file creation or truncation. This field MAY
 /// be ignored by the server</param>
 /// <param name="timeout">This field is a 32-bit unsigned integer value containing the number of milliseconds
 /// to wait on a blocked open request before returning without successfully opening the file.</param>
 /// <param name="fileName">A buffer containing the name of the file to be opened. </param>
 /// <param name="andxPacket">the andx packet.</param>
 /// <returns>a OpenAndx request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbOpenAndxRequestPacket CreateOpenAndxRequest(
     ushort uid,
     ushort treeId,
     Flags smbParametersFlags,
     AccessMode accessMode,
     SmbFileAttributes searchAttrs,
     SmbFileAttributes fileAttrs,
     UTime creationTime,
     OpenMode openMode,
     uint allocationSize,
     uint timeout,
     string fileName,
     SmbPacket andxPacket)
 {
     return this.CreateOpenAndxRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, smbParametersFlags, accessMode,
         searchAttrs, fileAttrs, creationTime, openMode, allocationSize, timeout, fileName, andxPacket);
 }
 /// <summary>
 /// to create a Open 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="accessMode">A 16-bit field for encoding the requested access mode. See section 3.2.4.5.1 for a
 /// discussion on sharing modes.</param>
 /// <param name="searchAttributes">SMB_FILE_ATTRIBUTES  Specifies the type of file desired. This field is used
 /// as a search mask. Both the FileName and the SearchAttributes of a file MUST match for the file to be
 /// opened. </param>
 /// <param name="fileName">STRING A null-terminated string containing the file name of the file to be
 /// opened.</param>
 /// <returns> to create a Open request packet.</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbOpenRequestPacket CreateOpenRequest(
     ushort uid,
     ushort treeId,
     AccessMode accessMode,
     SmbFileAttributes searchAttributes,
     string fileName)
 {
     return this.CreateOpenRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, accessMode, searchAttributes, fileName);
 }
        /// <summary>
        /// to create a OpenAndx 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="smbParametersFlags">A 16-bit field of flags for requesting attribute data and locking</param>
        /// <param name="accessMode">A 16-bit field for encoding the requested access mode. See section 3.2.4.5.1 for a
        /// discussion on sharing modes</param>
        /// <param name="searchAttrs">ATTRIBUTES The set of attributes that the file MUST have in order to be found
        /// while searching to see if it exists. If none of the attribute bytes are set, the file attributes MUST refer
        /// to a regular file.</param>
        /// <param name="fileAttrs">The set of attributes that the file is to have if the file needs to be created. If
        /// none of the attribute bytes are set, the file attributes MUST refer to a regular file.</param>
        /// <param name="creationTime">32-bit integer time value to be assigned to the file as a time of creation if
        /// the file is to be created. </param>
        /// <param name="openMode">A 16-bit field that controls the way a file SHOULD be treated when it is opened for
        /// use by certain extended SMB requests</param>
        /// <param name="allocationSize">The number of bytes to reserve on file creation or truncation. This field MAY
        /// be ignored by the server</param>
        /// <param name="timeout">This field is a 32-bit unsigned integer value containing the number of milliseconds
        /// to wait on a blocked open request before returning without successfully opening the file.</param>
        /// <param name="fileName">A buffer containing the name of the file to be opened. </param>
        /// <param name="andxPacket">the andx packet.</param>
        /// <returns>a OpenAndx request packet</returns>
        public SmbOpenAndxRequestPacket CreateOpenAndxRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            Flags smbParametersFlags,
            AccessMode accessMode,
            SmbFileAttributes searchAttrs,
            SmbFileAttributes fileAttrs,
            UTime creationTime,
            OpenMode openMode,
            uint allocationSize,
            uint timeout,
            string fileName,
            SmbPacket andxPacket)
        {
            if (fileName == null)
            {
                fileName = string.Empty;
            }

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

            SMB_COM_OPEN_ANDX_Request_SMB_Parameters smbParameters = new SMB_COM_OPEN_ANDX_Request_SMB_Parameters();
            smbParameters.AndXReserved = 0;
            smbParameters.Reserved = new ushort[2]; // the correct length of Reserved word is always 2.
            if (andxPacket == null)
            {
                smbParameters.AndXCommand = SmbCommand.SMB_COM_NO_ANDX_COMMAND;
            }
            else
            {
                smbParameters.AndXCommand = andxPacket.SmbHeader.Command;
            }
            smbParameters.Flags = smbParametersFlags;
            smbParameters.AccessMode = accessMode;
            smbParameters.SearchAttrs = searchAttrs;
            smbParameters.FileAttrs = fileAttrs;
            smbParameters.CreationTime = creationTime;
            smbParameters.OpenMode = openMode;
            smbParameters.AllocationSize = allocationSize;
            smbParameters.Timeout = timeout;
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_OPEN_ANDX_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            SMB_COM_OPEN_ANDX_Request_SMB_Data smbData = new SMB_COM_OPEN_ANDX_Request_SMB_Data();
            if ((flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
            {
                // if Unicode, add 1 byte pad for align on 16-bits.
                smbData.FileName = new byte[1 + (fileName.Length + 1) * 2];
                Array.Copy(CifsMessageUtils.ToSmbStringBytes(fileName, true), 0, smbData.FileName, 1,
                    (fileName.Length + 1) * 2);
            }
            else
            {
                smbData.FileName = CifsMessageUtils.ToSmbStringBytes(fileName, false);
            }
            smbData.ByteCount = (ushort)smbData.FileName.Length;

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

            return packet;
        }
 /// <summary>
 /// to create a FindUnique 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="maxCount">The maximum number of directory entries to return</param>
 /// <param name="searchAttributes">ATTRIBUTES  An attribute mask used to specify the standard attributes a file
 /// MUST have in order to match the search</param>
 /// <param name="fileName">null-terminated SMB_STRING. This is the full directory path (relative to the TID) of
 /// the file(s) being sought</param>
 /// <returns>a FindUnique request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbFindUniqueRequestPacket CreateFindUniqueRequest(
     ushort uid,
     ushort treeId,
     ushort maxCount,
     SmbFileAttributes searchAttributes,
     string fileName)
 {
     return this.CreateFindUniqueRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, maxCount, searchAttributes, fileName, null);
 }
 /// <summary>
 /// to create a Delete 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="searchAttributes">The file attributes of the file(s) to be deleted. If the value of this field
 /// is zero, then only normal files MUST be matched for deletion.  If the System or Hidden attributes MUST be
 /// specified, then entries with those attributes are matched in addition to the normal files.  Read-only files
 /// MAY NOT be deleted. The read-only attribute of the file MUST be cleared before the file MAY be
 /// deleted.</param>
 /// <param name="fileNames">The pathname of the file(s) to be deleted, relative to the supplied TID. Wildcards
 /// MAY be used in the filename component of the path.</param>
 /// <returns>a Delete request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbDeleteRequestPacket CreateDeleteRequest(
     ushort uid,
     ushort treeId,
     SmbFileAttributes searchAttributes,
     string[] fileNames)
 {
     return this.CreateDeleteRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, searchAttributes, fileNames);
 }
 /// <summary>
 /// to create a Trans2Open2 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="open2Flags">This 16-bit field of flags is used to request that the server take certain
 /// actions.</param>
 /// <param name="desiredAccess">A 16-bit field for encoding the requested access mode. See section 3.2.4.5.1
 /// for a discussion on sharing modes</param>
 /// <param name="creationTimeInSeconds">A time value expressed in seconds past Jan 1, 1970 00:00:00:00 to apply
 /// to the file's attributes if the file is created</param> 
 /// <param name="fileAttributes">Attributes to apply to the file if it needs to be created.</param> 
 /// <param name="openMode">A 16-bit field that controls the way a file SHOULD be treated when it is opened for
 /// use by certain extended SMB requests</param>  
 /// <param name="allocationSize">The number of bytes to reserve for the file if the file is being created or
 /// truncated. </param>
 /// <param name="name">A buffer containing the name of the file to be opened, created, or truncated. The
 /// string MUST be null terminated</param>
 /// <param name="extendedAttributeList">A list of extended file attribute name / value pairs that are to be
 /// assigned to the file.</param> 
 /// <returns>a Trans2Open2 request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbTrans2Open2RequestPacket CreateTrans2Open2Request(
     ushort uid,
     ushort treeId,
     Trans2Open2Flags open2Flags,
     Trans2Open2DesiredAccess desiredAccess,
     SmbFileAttributes fileAttributes,
     uint creationTimeInSeconds,
     OpenMode openMode,
     uint allocationSize,
     string name,
     SMB_FEA[] extendedAttributeList)
 {
     return this.CreateTrans2Open2Request(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, this.defaultParameters.MaxParameterCount,
         this.defaultParameters.MaxDataCount, this.defaultParameters.MaxSetupCount, this.defaultParameters.Trans2SmbParametersFlags,
         this.defaultParameters.Timeout, open2Flags, desiredAccess, fileAttributes, creationTimeInSeconds,
         openMode, allocationSize, name, extendedAttributeList);
 }
 /// <summary>
 /// to create a Rename 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="searchAttributes">The file attributes of the file(s) to be deleted. If the value of this field
 /// is zero, then only normal files MUST be matched for deletion.  If the System or Hidden attributes MUST be
 /// specified, then entries with those attributes are matched in addition to the normal files.  Read-only files
 /// MAY NOT be deleted. The read-only attribute of the file MUST be cleared before the file MAY be
 /// deleted.</param>
 /// <param name="oldFileName">A null-terminated string containing the name of the file or files to be renamed.
 /// Wildcards MAY be used in the filename component of the path</param>
 /// <param name="newFileName">A null-terminated string containing the new name(s) to be given to the file(s)
 /// that matches OldFileName or the name of the destination directory into which the files matching OldFileName
 /// MUST be moved.</param>
 /// <returns>a Rename request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbRenameRequestPacket CreateRenameRequest(
     ushort uid,
     ushort treeId,
     SmbFileAttributes searchAttributes,
     string oldFileName,
     string newFileName)
 {
     return this.CreateRenameRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, searchAttributes, oldFileName, newFileName);
 }
        /// <summary>
        /// to create a Create 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="fileAttributes">A 16-bit field of 1-bit flags that represent the file attributes to assign
        /// to the file if it is created successfully.</param>
        /// <param name="creationTime">UTIME The time the file was created on the client represented as the number
        /// of seconds since Jan 1, 1970, 00:00:00.0. Server support of this field is OPTIONAL</param>
        /// <param name="fileName">A null-terminated string that represents the fully qualified name of the file
        /// relative to the supplied TID to create or truncate on the server.</param>
        /// <returns>a Open request packet</returns>
        public SmbCreateRequestPacket CreateCreateRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            SmbFileAttributes fileAttributes,
            UTime creationTime,
            string fileName)
        {
            if (fileName == null)
            {
                fileName = string.Empty;
            }

            SmbCreateRequestPacket packet = new SmbCreateRequestPacket();

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

            SMB_COM_CREATE_Request_SMB_Parameters smbParameters = new SMB_COM_CREATE_Request_SMB_Parameters();
            smbParameters.FileAttributes = fileAttributes;
            smbParameters.CreationTime = creationTime;
            smbParameters.WordCount = (byte)(Marshal.SizeOf(smbParameters) / NumBytesOfWord);

            SMB_COM_CREATE_Request_SMB_Data smbData = new SMB_COM_CREATE_Request_SMB_Data();
            smbData.BufferFormat = (byte)DataBufferFormat.SmbString;
            smbData.FileName = CifsMessageUtils.ToSmbStringBytes(fileName,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);
            smbData.ByteCount = (ushort)(Marshal.SizeOf(smbData.BufferFormat) + smbData.FileName.Length);

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

            return packet;
        }
        /// <summary>
        /// to create a Search 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="maxCount">The maximum number of directory entries to return</param>
        /// <param name="searchAttributes">ATTRIBUTES  An attribute mask used to specify the standard attributes a file
        /// MUST have in order to match the search</param>
        /// <param name="fileName">null-terminated SMB_STRING. This is the full directory path (relative to the TID) of
        /// the file(s) being sought</param>
        /// <param name="resumeKey">The ResumeKey contains data used by both the client and the server to maintain the
        /// state of the search</param>
        /// <returns>a Search request packet</returns>
        public SmbSearchRequestPacket CreateSearchRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            ushort maxCount,
            SmbFileAttributes searchAttributes,
            string fileName,
            SMB_Resume_Key[] resumeKey)
        {
            if (fileName == null)
            {
                fileName = string.Empty;
            }
            if (resumeKey == null)
            {
                resumeKey = new SMB_Resume_Key[0];
            }

            SmbSearchRequestPacket packet = new SmbSearchRequestPacket();

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

            SMB_COM_SEARCH_Request_SMB_Parameters smbParameters = new SMB_COM_SEARCH_Request_SMB_Parameters();
            smbParameters.MaxCount = maxCount;
            smbParameters.SearchAttributes = searchAttributes;
            smbParameters.WordCount = (byte)(Marshal.SizeOf(smbParameters) / NumBytesOfWord);

            SMB_COM_SEARCH_Request_SMB_Data smbData = new SMB_COM_SEARCH_Request_SMB_Data();
            int resumeKeySize = 0;
            if (resumeKey.Length > 0)
            {
                resumeKeySize = CifsMessageUtils.GetSize<SMB_Resume_Key>(resumeKey[0]);
            }
            smbData.BufferFormat1 = (byte)DataBufferFormat.SmbString;
            smbData.BufferFormat2 = (byte)DataBufferFormat.VariableBlock;
            smbData.ResumeKey = resumeKey;
            smbData.ResumeKeyLength = (ushort)resumeKeySize;
            smbData.FileName = CifsMessageUtils.ToSmbStringBytes(fileName,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);
            smbData.ByteCount = (ushort)(Marshal.SizeOf(smbData.BufferFormat1) + smbData.FileName.Length
                + Marshal.SizeOf(smbData.BufferFormat2) + Marshal.SizeOf(smbData.ResumeKeyLength)
                + smbData.ResumeKeyLength);

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

            return packet;
        }
        /// <summary>
        /// to create a Delete 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="searchAttributes">The file attributes of the file(s) to be deleted. If the value of this
        /// field is zero, then only normal files MUST be matched for deletion.  If the System or Hidden attributes
        /// MUST be specified, then entries with those attributes are matched in addition to the normal files.  
        /// Read-only files MAY NOT be deleted. The read-only attribute of the file MUST be cleared before the file
        /// MAY be deleted.</param>
        /// <param name="fileNames">The pathname of the file(s) to be deleted, relative to the supplied TID. Wildcards
        /// MAY be used in the filename component of the path.</param>
        /// <returns>a Delete request packet</returns>
        public SmbDeleteRequestPacket CreateDeleteRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            SmbFileAttributes searchAttributes,
            string[] fileNames)
        {
            if (fileNames == null)
            {
                fileNames = new string[0];
            }

            SmbDeleteRequestPacket packet = new SmbDeleteRequestPacket();

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

            SMB_COM_DELETE_Request_SMB_Parameters smbParameters = new SMB_COM_DELETE_Request_SMB_Parameters();
            smbParameters.SearchAttributes = searchAttributes;
            smbParameters.WordCount = (byte)(Marshal.SizeOf(smbParameters) / NumBytesOfWord);

            SMB_COM_DELETE_Request_SMB_Data smbData = new SMB_COM_DELETE_Request_SMB_Data();
            smbData.ByteCount = 0;
            smbData.BufferFormatAndFileName = new byte[0];
            bool isUnicode = (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE;
            const int bufferFormatSize = 1; // the size in bytes of BufferFormat is always 1.
            const int nullTerminalSize = 1; // the num of null Terminal character is always 1.
            foreach (string file in fileNames)
            {
                if (isUnicode)
                {
                    smbData.ByteCount += (byte)(bufferFormatSize + (file.Length + nullTerminalSize) * 2);
                }
                else
                {
                    smbData.ByteCount += (byte)(bufferFormatSize + (file.Length + nullTerminalSize));
                }
            }
            smbData.BufferFormatAndFileName = new byte[smbData.ByteCount];
            int index = 0;
            foreach (string file in fileNames)
            {
                smbData.BufferFormatAndFileName[index++] = (byte)DataBufferFormat.SmbString;
                byte[] fileNameBytes = CifsMessageUtils.ToSmbStringBytes(file, isUnicode);
                Array.Copy(fileNameBytes, 0, smbData.BufferFormatAndFileName, index, fileNameBytes.Length);
                index += fileNameBytes.Length;
            }

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

            return packet;
        }
 /// <summary>
 /// to create a Search 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="maxCount">The maximum number of directory entries to return</param>
 /// <param name="searchAttributes">ATTRIBUTES  An attribute mask used to specify the standard attributes a file
 /// MUST have in order to match the search</param>
 /// <param name="fileName">null-terminated SMB_STRING. This is the full directory path (relative to the TID) of
 /// the file(s) being sought</param>
 /// <param name="resumeKey">The ResumeKey contains data used by both the client and the server to maintain the
 /// state of the search</param>
 /// <returns>a Search request packet</returns>
 /// <exception cref="System.NullReferenceException">There is no connection in context. </exception>
 public SmbSearchRequestPacket CreateSearchRequest(
     ushort uid,
     ushort treeId,
     ushort maxCount,
     SmbFileAttributes searchAttributes,
     string fileName,
     SMB_Resume_Key[] resumeKey)
 {
     return this.CreateSearchRequest(this.Context.GetMessageId(this.connectionId),
         uid, treeId, this.defaultParameters.Flag, this.defaultParameters.Flag2, maxCount,
         searchAttributes, fileName, resumeKey);
 }
 /// <summary>
 /// Create Trans2FindFirst2 request for the client to find file on server. 
 /// </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 = "fileName">The file name to find. </param>
 /// <param name = "transactOptions">
 /// A set of bit flags that alter the behavior of the requested operation. Unused bit fields MUST be set to  
 /// zero by the client sending the request, and MUST be ignored by the server receiving the request. The 
 /// client MAY set either or both of the following bit flags 
 /// </param>
 /// <param name = "timeOut">
 /// The maximum amount of time in milliseconds to wait for the operation to complete. The client SHOULD set  
 /// this to 0 to indicate that no time-out is given. If the operation does not complete within the specified  
 /// time, the server MAY abort the request and send a failure response. 
 /// </param>
 /// <param name = "searchCount">
 /// The server MUST NOT return more entries than indicated by the value of this field. 
 /// </param>
 /// <param name = "findFlags">
 /// This 16-bit field of flags is used to request that the server take certain actions. 
 /// </param>
 /// <param name = "searchAttributes">File attributes to apply as a constraint to the file search. </param>
 /// <param name = "searchStorageType">
 /// This field specifies if the find is searching for directories or for files.This field MUST be one of two  
 /// values 
 /// </param>
 /// <param name = "informationLevel">
 /// Indicates that client specifies the information it is requesting. Server return different data based on 
 /// the client's request. 
 /// </param>
 /// <returns>a find file for the first request packet </returns>
 private SmbTrans2FindFirst2RequestPacket CreateTrans2FindFirst2Request(
     ushort messageId,
     ushort sessionUid,
     ushort treeId,
     SmbHeader_Flags_Values flags,
     SmbHeader_Flags2_Values flags2,
     string fileName,
     Trans2SmbParametersFlags transactOptions,
     uint timeOut,
     ushort searchCount,
     Trans2FindFlags findFlags,
     SmbFileAttributes searchAttributes,
     Trans2FindFirst2SearchStorageType searchStorageType,
     FindInformationLevel informationLevel)
 {
     return new SmbTrans2FindFirst2RequestPacket(
         this.cifsClient.CreateTrans2FindFirst2Request(
         messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
         this.capability.MaxParameterCount, this.capability.MaxDataCount, this.capability.MaxSetupCount,
         transactOptions, timeOut, searchAttributes, searchCount,
         findFlags, (Cifs.FindInformationLevel)informationLevel, searchStorageType, fileName, null));
 }
        /// <summary>
        /// to create a SetInformation 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="fileAttributes">This field is a 16 bit unsigned bit field encoded as 
        /// SMB_FILE_ATTRIBUTES</param>
        /// <param name="lastWriteTime">The time of the last write to the file</param>
        /// <param name="fileName">A null-terminated string that represents the fully qualified name of the file 
        /// relative to the supplied TID. This is the file for which attributes are set.</param>
        /// <returns>a SetInformation request packet</returns>
        public SmbSetInformationRequestPacket CreateSetInformationRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            SmbFileAttributes fileAttributes,
            UTime lastWriteTime,
            string fileName)
        {
            if (fileName == null)
            {
                fileName = string.Empty;
            }

            SmbSetInformationRequestPacket packet = new SmbSetInformationRequestPacket();

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

            SMB_COM_SET_INFORMATION_Request_SMB_Parameters smbParameters;
            smbParameters = new SMB_COM_SET_INFORMATION_Request_SMB_Parameters();
            smbParameters.FileAttributes = fileAttributes;
            smbParameters.LastWriteTime = lastWriteTime;
            smbParameters.Reserved = new ushort[5]; // the correct length of Reserved word is always 5.
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_SET_INFORMATION_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            SMB_COM_SET_INFORMATION_Request_SMB_Data smbData = new SMB_COM_SET_INFORMATION_Request_SMB_Data();
            smbData.BufferFormat = (byte)DataBufferFormat.SmbString;
            smbData.FileName = CifsMessageUtils.ToSmbStringBytes(fileName,
                (flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE);
            smbData.ByteCount = (ushort)(Marshal.SizeOf(smbData.BufferFormat) + smbData.FileName.Length);

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

            return packet;
        }
        /// <summary>
        /// Create Trans2FindFirst2 request for the client to find file on server. 
        /// </summary>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "fileName">The file name to find. </param>
        /// <param name = "transactOptions">
        /// A set of bit flags that alter the behavior of the requested operation. Unused bit fields MUST be set to  
        /// zero by the client sending the request, and MUST be ignored by the server receiving the request. The 
        /// client MAY set either or both of the following bit flags 
        /// </param>
        /// <param name = "searchCount">
        /// The server MUST NOT return more entries than indicated by the value of this field. 
        /// </param>
        /// <param name = "findFlags">
        /// This 16-bit field of flags is used to request that the server take certain actions. 
        /// </param>
        /// <param name = "searchAttributes">File attributes to apply as a constraint to the file search. </param>
        /// <param name = "searchStorageType">
        /// This field specifies if the find is searching for directories or for files. This field MUST be one of two  
        /// values 
        /// </param>
        /// <param name = "isReparsePath">If true, the path in the request MUST contain an @GMT token. </param>
        /// <param name = "isKnowsLongName">
        /// is used to indicate to set the SMB_FLAGS2_KNOWS_LONG_NAMES flag in smb header or not. 
        /// </param>
        /// <param name = "informationLevel">
        /// Indicates that client specifies the information it is requesting. Server return different data based on 
        /// the client's request. 
        /// </param>
        /// <returns>a find file for the first request packet </returns>
        public virtual SmbTrans2FindFirst2RequestPacket CreateTrans2FindFirst2Request(
            ushort treeId,
            string fileName,
            Trans2SmbParametersFlags transactOptions,
            ushort searchCount,
            Trans2FindFlags findFlags,
            SmbFileAttributes searchAttributes,
            Trans2FindFirst2SearchStorageType searchStorageType,
            bool isReparsePath,
            bool isKnowsLongName,
            FindInformationLevel informationLevel)
        {
            SmbHeader_Flags2_Values flags2 = this.capability.Flags2;
            // update flags2 of header
            if (isReparsePath)
            {
                flags2 |= SmbHeader_Flags2_Values.SMB_FLAGS2_REPARSE_PATH;
            }

            if (isKnowsLongName)
            {
                flags2 |= SmbHeader_Flags2_Values.SMB_FLAGS2_KNOWS_LONG_NAMES;
            }
            return CreateTrans2FindFirst2Request(this.MessageId,
                this.GetSessionIdByTreeId(treeId), treeId,
               this.capability.Flag, flags2, fileName, transactOptions,
                this.capability.Timeout, searchCount, findFlags, searchAttributes, searchStorageType,
                informationLevel);
        }
        public SmbQueryInformation2ResponsePacket CreateQueryInformation2Response(
            CifsServerPerConnection connection,
            SmbQueryInformation2RequestPacket request,
            SmbDate createDate,
            SmbTime createTime,
            SmbDate lastAccessDate,
            SmbTime lastAccessTime,
            SmbDate lastWriteDate,
            SmbTime lastWriteTime,
            uint fileDataSize,
            uint fileAllocationSize,
            SmbFileAttributes fileAttributes)
        {
            SmbQueryInformation2ResponsePacket response = new SmbQueryInformation2ResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            SMB_COM_QUERY_INFORMATION2_Response_SMB_Parameters smbParameters = response.SmbParameters;
            smbParameters.CreateDate = createDate;
            smbParameters.CreationTime = createTime;
            smbParameters.LastAccessDate = lastAccessDate;
            smbParameters.LastAccessTime = lastAccessTime;
            smbParameters.LastWriteDate = lastWriteDate;
            smbParameters.LastWriteTime = lastWriteTime;
            smbParameters.FileDataSize = fileDataSize;
            smbParameters.FileAllocationSize = fileAllocationSize;
            smbParameters.FileAttributes = fileAttributes;
            smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2);
            response.SmbParameters = smbParameters;

            return response;
        }