/// <summary>
 /// Deep copy constructor.
 /// </summary>
 public SmbNtTransactNotifyChangeRequestPacket(SmbNtTransactNotifyChangeRequestPacket packet)
     : base(packet)
 {
     this.InitDefaultValue();
 }
        /// <summary>
        /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse().
        /// </summary>
        /// <param name="timeout">timeout</param>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="session">the session between server and client</param>
        /// <param name="treeConnect">the tree connect between server and client</param>
        /// <param name="open">the file open between server and client</param>
        /// <param name="requestPacket">the request</param>
        public override void ExpectRequest(
            TimeSpan timeout,
            out IFileServiceServerConnection connection,
            out IFileServiceServerSession session,
            out IFileServiceServerTreeConnect treeConnect,
            out IFileServiceServerOpen open,
            out SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection;
            SmbPacket request = this.cifsServer.ExpectPacket(timeout, out cifsConnection);

            connection    = cifsConnection;
            requestPacket = request;
            session       = null;
            treeConnect   = null;
            open          = null;

            if (request != null)
            {
                session = cifsConnection.GetSession(request.SmbHeader.Uid);
                if (session != null)
                {
                    treeConnect = (session as CifsServerPerSession).GetTreeConnect(request.SmbHeader.Tid);
                    if (treeConnect != null)
                    {
                        ushort fid = 0;
                        SmbTransactionRequestPacket            transactionRequest = request as SmbTransactionRequestPacket;
                        SmbNtTransactIoctlRequestPacket        ioctlRequest       = request as SmbNtTransactIoctlRequestPacket;
                        SmbNtTransactNotifyChangeRequestPacket notifyChange       = request as SmbNtTransactNotifyChangeRequestPacket;

                        if (transactionRequest != null)
                        {
                            //SubCommand(2bytes), FID(2bytes)
                            fid = transactionRequest.SmbParameters.Setup[1];
                        }

                        else if (ioctlRequest != null)
                        {
                            //FunctionCode(4bytes), FID(2bytes), IsFctl(1bytes), IsFlags(1bytes)
                            fid = ioctlRequest.SmbParameters.Setup[2];
                        }
                        else if (notifyChange != null)
                        {
                            //CompletionFilter(4bytes), FID(2bytes), WatchTree(1bytes), Reserved(1bytes)
                            fid = notifyChange.SmbParameters.Setup[2];
                        }
                        else
                        {
                            Type         packetType = request.GetType();
                            PropertyInfo pi         = packetType.GetProperty(
                                "Trans2Parameters", BindingFlags.Instance | BindingFlags.Public);

                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "NtTransParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "SmbParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi != null)
                            {
                                object    smbParameters = pi.GetValue(request, null);
                                FieldInfo fi            = smbParameters.GetType().GetField(
                                    "FID",
                                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
                                if (fi != null)
                                {
                                    fid = (ushort)fi.GetValue(smbParameters);
                                }
                            }
                        }

                        if (fid > 0)
                        {
                            open = (treeConnect as CifsServerPerTreeConnect).GetOpen(fid);
                        }
                    }
                }
            }
        }
        public SmbNtTransactNotifyChangeResponsePacket CreateNtTransactNotifyChangeResponse(
            CifsServerPerConnection connection,
            SmbNtTransactNotifyChangeRequestPacket request,
            FILE_NOTIFY_INFORMATION[] fileNotifyInformation)
        {
            SmbNtTransactNotifyChangeResponsePacket response = new SmbNtTransactNotifyChangeResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            NT_TRANSACT_NOTIFY_CHANGE_Response_NT_Trans_Parameters ntTransParameters = response.NtTransParameters;
            ntTransParameters.FileNotifyInformation = fileNotifyInformation;
            response.NtTransParameters = ntTransParameters;

            response.UpdateCountAndOffset();

            return response;
        }
        /// <summary>
        /// to create a NtTransactNotifyChange 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="fid">MUST contain a valid FID obtained from a previously successful SMB open command.</param>
        /// <param name="filter">Specify the types of operations to monitor.</param>
        /// <param name="watchTree">BOOLEAN If all subdirectories are to be watched, then set this to TRUE; otherwise,
        /// FALSE.</param>
        /// <returns>a NtTransactNotifyChange request packet</returns>
        public SmbNtTransactNotifyChangeRequestPacket CreateNtTransactNotifyChangeRequest(
            ushort messageId,
            ushort uid,
            ushort treeId,
            SmbFlags flags,
            SmbFlags2 flags2,
            byte maxSetupCount,
            uint maxParameterCount,
            uint maxDataCount,
            ushort fid,
            CompletionFilter filter,
            bool watchTree)
        {
            SmbNtTransactNotifyChangeRequestPacket packet = new SmbNtTransactNotifyChangeRequestPacket();
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_NT_TRANSACT,
                messageId, uid, treeId, flags, flags2);

            // Set Smb_Parameters
            SMB_COM_NT_TRANSACT_Request_SMB_Parameters smbParameters =
                new SMB_COM_NT_TRANSACT_Request_SMB_Parameters();
            smbParameters.MaxSetupCount = maxSetupCount;
            smbParameters.MaxParameterCount = maxParameterCount;
            smbParameters.MaxDataCount = maxDataCount;
            smbParameters.SetupCount = 4; // the cout of Setup is 4.
            smbParameters.Function = NtTransSubCommand.NT_TRANSACT_NOTIFY_CHANGE;
            NT_TRANSACT_NOTIFY_SETUP setupStruct = new NT_TRANSACT_NOTIFY_SETUP();
            setupStruct.filter = filter;
            setupStruct.Fid = fid;
            setupStruct.WatchTree = (byte)(watchTree ? 1 : 0);
            smbParameters.Setup = CifsMessageUtils.ToTypeArray<ushort>(CifsMessageUtils.ToBytes<NT_TRANSACT_NOTIFY_SETUP
                >(setupStruct));
            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_Request_SMB_Parameters>(
                smbParameters) / NumBytesOfWord);

            // Set Smb_Data
            SMB_COM_NT_TRANSACT_Request_SMB_Data smbData = new SMB_COM_NT_TRANSACT_Request_SMB_Data();

            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.UpdateCountAndOffset();

            return packet;
        }
 /// <summary>
 /// Deep copy constructor.
 /// </summary>
 public SmbNtTransactNotifyChangeRequestPacket(SmbNtTransactNotifyChangeRequestPacket packet)
     : base(packet)
 {
     this.InitDefaultValue();
 }