public Smb2IOCtlResponsePacket CreateSnapshotIOCtlResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            ulong messageId,
            SRV_SNAPSHOT_ARRAY snapshots
            )
        {
            Smb2IOCtlResponsePacket packet = CreateSnapshotIOCtlResponse(endpoint, messageId, snapshots);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        public Smb2LeaseBreakResponsePacket CreateLeaseBreakResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            LeaseStateValues leaseState
            )
        {
            Smb2LeaseBreakResponsePacket packet = new Smb2LeaseBreakResponsePacket();

            SetHeader(packet, endpoint, messageId);

            Smb2LeaseBreakAckPacket leaseBreakAck = context.FindRequestPacket(endpoint.EndpointId, messageId)
                as Smb2LeaseBreakAckPacket;

            packet.PayLoad.Flags = LEASE_BREAK_Response_Packet_Flags_Values.V1;
            packet.PayLoad.LeaseDuration = LEASE_BREAK_Response_Packet_LeaseDuration_Values.V1;
            packet.PayLoad.LeaseKey = leaseBreakAck.PayLoad.LeaseKey;
            packet.PayLoad.LeaseState = leaseState;
            packet.PayLoad.Reserved = LEASE_BREAK_Response_Reserved_Values.V1;
            packet.PayLoad.StructureSize = LEASE_BREAK_Response_StructureSize_Values.V1;

            packet.Sign();

            return packet;
        }
        public Smb2LogOffResponsePacket CreateLogoffResponse(
            Smb2Endpoint endpoint,
            ulong messageId
            )
        {
            Smb2LogOffResponsePacket packet = new Smb2LogOffResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.Reserved = LOGOFF_Response_Reserved_Values.V1;
            packet.PayLoad.StructureSize = LOGOFF_Response_StructureSize_Values.V1;

            packet.Sign();

            return packet;
        }
        public Smb2ErrorResponsePacket CreateErrorResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            uint status,
            ulong messageId,
            byte[] errorData
            )
        {
            Smb2ErrorResponsePacket packet = CreateErrorResponse(endpoint, status, messageId, errorData);

            packet.Header.Flags |= Packet_Header_Flags_Values.FLAGS_ASYNC_COMMAND;
            packet.Header.ProcessId = (uint)asyncId;
            packet.Header.TreeId = (uint)(asyncId >> 32);

            packet.Sign();

            return packet;
        }
        public Smb2IOCtlResponsePacket CreateIOCtlResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            ulong messageId,
            byte[] input,
            byte[] output
            )
        {
            Smb2IOCtlResponsePacket packet = CreateIOCtlResponse(endpoint, messageId, input, output);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        public Smb2IOCtlResponsePacket CreateCopyChunkIOCtlResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            ulong messageId,
            SRV_COPYCHUNK_RESPONSE copyChunk
            )
        {
            Smb2IOCtlResponsePacket packet = CreateCopyChunkIOCtlResponse(endpoint, messageId, copyChunk);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        public Smb2CreateResponsePacket CreateCreateResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            ulong messageId,
            OplockLevel_Values oplockLevel,
            CreateAction_Values createAction,
            _FILETIME creationTime,
            _FILETIME lastAccessTime,
            _FILETIME lastWriteTime,
            _FILETIME changeTime,
            ulong allocationSize,
            ulong endofFile,
            File_Attributes fileAttributes,
            FILEID fileId,
            params CREATE_CONTEXT_Values[] contexts
            )
        {
            Smb2CreateResponsePacket packet = CreateCreateResponse(endpoint, messageId, oplockLevel,
                createAction, creationTime, lastAccessTime, lastWriteTime, changeTime, allocationSize,
                endofFile, fileAttributes, fileId, contexts);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        /// <summary>
        /// Expect a packet from a client specified by the endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint of the client</param>
        /// <param name="timeout">The waiting time</param>
        /// <returns>A Smb2Packet</returns>
        /// <exception cref="System.InvalidOperationException">throw when receive a packet which does not pass signature check</exception>
        /// <exception cref="System.InvalidOperationException">Receive unexpected packet</exception>
        public Smb2Packet ExpectPacket(out Smb2Endpoint endpoint, TimeSpan timeout)
        {
            TransportEvent transEvent = transport.ExpectTransportEvent(timeout);

            if (transEvent.EventType == EventType.Exception)
            {
                throw new InvalidOperationException("Received un-expected packet, packet type is not correct", (Exception)transEvent.EventObject);
            }

            if (transEvent.EventType != EventType.ReceivedPacket)
            {
                throw new InvalidOperationException("Received un-expected packet, packet type is not correct");
            }

            Smb2Event smb2Event = new Smb2Event();
            smb2Event.Type = Smb2EventType.PacketReceived;

            foreach (Smb2Endpoint smb2endpoint in clientEndpoints)
            {
                if (smb2endpoint.TransportType == Smb2TransportType.NetBios)
                {
                    if ((object)smb2endpoint.SessionId == transEvent.EndPoint)
                    {
                        endpoint = smb2endpoint;

                        smb2Event.Packet = (Smb2Packet)transEvent.EventObject;
                        smb2Event.ConnectionId = smb2endpoint.EndpointId;

                        context.UpdateContext(smb2Event);

                        return (Smb2Packet)transEvent.EventObject;
                    }
                }
                else if (smb2endpoint.TransportType == Smb2TransportType.Tcp)
                {
                    if ((object)smb2endpoint.RemoteEndpoint == transEvent.EndPoint)
                    {
                        endpoint = smb2endpoint;

                        smb2Event.Packet = (Smb2Packet)transEvent.EventObject;
                        smb2Event.ConnectionId = smb2endpoint.EndpointId;

                        context.UpdateContext(smb2Event);

                        return (Smb2Packet)transEvent.EventObject;
                    }
                }
            }

            throw new InvalidOperationException("Received an un-expected packet, endpoint is not correct");
        }
        /// <summary>
        /// Send packet to a client specified by the endpoint, this method is for negative test, for normal use, please use
        /// SendPacket(Smb2Packet packet)
        /// </summary>
        /// <param name="endpoint">The client endpoint</param>
        /// <param name="packet">The packet</param>
        public void SendPacket(Smb2Endpoint endpoint, Smb2Packet packet)
        {
            Smb2Event smb2Event = new Smb2Event();
            smb2Event.ConnectionId = endpoint.EndpointId;
            smb2Event.Packet = packet;
            smb2Event.Type = Smb2EventType.PacketSent;

            context.UpdateContext(smb2Event);

            SendPacket(endpoint, packet.ToBytes());
        }
 /// <summary>
 /// Disconnect the client
 /// </summary>
 /// <param name="endpoint">The endpoint of the client</param>
 public void Disconnect(Smb2Endpoint endpoint)
 {
     Disconnect(endpoint, true);
 }
        /// <summary>
        /// Expect a client connection
        /// </summary>
        /// <param name="timeOut">The waiting time</param>
        /// <returns>The endpoint of the client</returns>
        public Smb2Endpoint ExpectConnection(TimeSpan timeOut)
        {
            TransportEvent transEvent = transport.ExpectTransportEvent(timeOut);

            if (transEvent.EventType != EventType.Connected)
            {
                throw new InvalidOperationException("Reveived an un-expected transport event");
            }

            Smb2Endpoint endpoint;

            if (transportType == Smb2TransportType.NetBios)
            {
                endpoint = new Smb2Endpoint(Smb2TransportType.NetBios, null, (byte)transEvent.EndPoint, endpointId++);
            }
            else
            {
                endpoint = new Smb2Endpoint(Smb2TransportType.Tcp, (IPEndPoint)transEvent.EndPoint, 0, endpointId++);
            }

            Smb2Event smb2Event = new Smb2Event();
            smb2Event.Type = Smb2EventType.Connected;
            smb2Event.Packet = null;
            smb2Event.ConnectionId = endpoint.EndpointId;

            context.UpdateContext(smb2Event);

            clientEndpoints.Add(endpoint);
            return endpoint;
        }
        public Smb2WriteResponsePacket CreateWriteResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            uint count
            )
        {
            Smb2WriteResponsePacket packet = new Smb2WriteResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.Count = count;
            packet.PayLoad.Remaining = Remaining_Values.V1;
            packet.PayLoad.Reserved = WRITE_Response_Reserved_Values.V1;
            packet.PayLoad.StructureSize = WRITE_Response_StructureSize_Values.V1;
            packet.PayLoad.WriteChannelInfoLength = WRITE_Response_WriteChannelInfoLength_Values.V1;
            packet.PayLoad.WriteChannelInfoOffset = WRITE_Response_WriteChannelInfoOffset_Values.V1;

            packet.Sign();

            return packet;
        }
        public Smb2TreeDisconnectResponsePacket CreateTreeDisconnectResponse(
            Smb2Endpoint endpoint,
            ulong messageId
            )
        {
            Smb2TreeDisconnectResponsePacket packet = new Smb2TreeDisconnectResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.Reserved = TREE_DISCONNECT_Response_Reserved_Values.V1;
            packet.PayLoad.StructureSize = TREE_DISCONNECT_Response_StructureSize_Values.CorrectValue;

            packet.Sign();

            return packet;
        }
        public Smb2TreeConnectResponsePacket CreateTreeConnectResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            uint treeId,
            ShareType_Values shareType,
            ShareFlags_Values shareFlags,
            Capabilities_Values capabilities,
            _ACCESS_MASK maximalAccess
            )
        {
            Smb2TreeConnectResponsePacket packet = new Smb2TreeConnectResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.Header.TreeId = treeId;
            packet.PayLoad.Capabilities = capabilities;
            packet.PayLoad.MaximalAccess = maximalAccess;
            packet.PayLoad.Reserved = Reserved_Values.V1;
            packet.PayLoad.ShareFlags = shareFlags;
            packet.PayLoad.ShareType = shareType;
            packet.PayLoad.StructureSize = StructureSize_Values.V1;

            packet.Sign();

            return packet;
        }
        /// <summary>
        /// Create Smb2CompoundPacket
        /// </summary>
        /// <param name="endpoint">represents where this packet will be sent</param>
        /// <param name="packets">Variable number of Single packets</param>
        /// <returns>A Smb2CompoundPacket</returns>
        public Smb2CompoundPacket CreateCompoundResponse(
            Smb2Endpoint endpoint,
            params Smb2SinglePacket[] packets
            )
        {
            if (packets == null)
            {
                throw new ArgumentNullException("packets");
            }

            if (packets.Length < 2)
            {
                throw new ArgumentException("The number of packet should be larger than 1", "packets");
            }

            Smb2CompoundPacket packet = new Smb2CompoundPacket();
            packet.Packets = new List<Smb2SinglePacket>();

            //The endpoint of the compoundpacket comes from innerPacket.
            packet.Endpoint = packets[0].Endpoint;

            for (int i = 0; i < packets.Length; i++)
            {
                if (((packets[0].Header.Flags & Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS)
                    == Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS))
                {
                    packets[i].OuterCompoundPacket = packet;
                }

                if (i != (packets.Length - 1))
                {

                    packets[i].Header.NextCommand = (uint)Smb2Utility.AlignBy8Bytes(packets[i].ToBytes().Length);
                }
                else
                {
                    packets[i].IsLast = true;
                }

                packets[i].IsInCompoundPacket = true;

                packet.Packets.Add(packets[i]);
            }

            packet.Sign();

            return packet;
        }
 /// <summary>
 /// Send packet data to client
 /// </summary>
 /// <param name="endpoint">The client endpoint</param>
 /// <param name="packet">The packet data</param>
 public void SendPacket(Smb2Endpoint endpoint, byte[] packet)
 {
     if (transportType == Smb2TransportType.NetBios)
     {
         transport.SendBytes(endpoint.SessionId, packet);
     }
     else
     {
         transport.SendBytes(endpoint.RemoteEndpoint, Smb2Utility.GenerateTcpTransportPayLoad(packet));
     }
 }
        public Smb2IOCtlResponsePacket CreateCopyChunkIOCtlResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            SRV_COPYCHUNK_RESPONSE copyChunk
            )
        {
            byte[] output = TypeMarshal.ToBytes(copyChunk);

            return CreateIOCtlResponse(endpoint, messageId, null, output);
        }
        /// <summary>
        /// Disconnect the client
        /// </summary>
        /// <param name="endpoint">The endpoint of the client</param>
        /// <param name="removeEndpoint">Indicate whether the endpoint should be removed from endpointList</param>
        private void Disconnect(Smb2Endpoint endpoint, bool removeEndpoint)
        {
            if (!clientEndpoints.Contains(endpoint))
            {
                throw new ArgumentException("The endpoint is not in the server's client endpoint list.", "endpoint");
            }

            if (removeEndpoint)
            {
                clientEndpoints.Remove(endpoint);
            }

            Smb2Event smb2Event = new Smb2Event();
            smb2Event.Type = Smb2EventType.Disconnected;
            smb2Event.Packet = null;
            smb2Event.ConnectionId = endpoint.EndpointId;

            context.UpdateContext(smb2Event);

            if (transportType == Smb2TransportType.NetBios)
            {
                transport.Disconnect(endpoint.SessionId);
            }
            else
            {
                transport.Disconnect(endpoint.RemoteEndpoint);
            }
        }
        public Smb2CreateResponsePacket CreateCreateResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            OplockLevel_Values oplockLevel,
            CreateAction_Values createAction,
            _FILETIME creationTime,
            _FILETIME lastAccessTime,
            _FILETIME lastWriteTime,
            _FILETIME changeTime,
            ulong allocationSize,
            ulong endofFile,
            File_Attributes fileAttributes,
            FILEID fileId,
            params CREATE_CONTEXT_Values[] createContexts
            )
        {
            Smb2CreateResponsePacket packet = new Smb2CreateResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.StructureSize = CREATE_Response_StructureSize_Values.V1;
            packet.PayLoad.OplockLevel = oplockLevel;
            packet.PayLoad.Reserved = 0;
            packet.PayLoad.CreateAction = createAction;
            packet.PayLoad.CreationTime = creationTime;
            packet.PayLoad.LastAccessTime = lastAccessTime;
            packet.PayLoad.LastWriteTime = lastWriteTime;
            packet.PayLoad.ChangeTime = changeTime;
            packet.PayLoad.AllocationSize = allocationSize;
            packet.PayLoad.EndofFile = endofFile;
            packet.PayLoad.FileAttributes = fileAttributes;
            packet.PayLoad.Reserved2 = 0;
            packet.PayLoad.FileId = fileId;

            if (createContexts == null)
            {
                packet.PayLoad.CreateContextsOffset = 0;
                packet.PayLoad.CreateContextsLength = 0;
                packet.PayLoad.Buffer = new byte[0];
            }
            else
            {
                packet.PayLoad.CreateContextsOffset = Smb2Consts.CreateContextOffsetInCreateResponse;

                using (MemoryStream ms = new MemoryStream())
                {
                    for (int i = 0; i < createContexts.Length; i++)
                    {
                        byte[] createContext = TypeMarshal.ToBytes(createContexts[i]);

                        if (i != (createContexts.Length - 1))
                        {
                            int alignedLen = Smb2Utility.AlignBy8Bytes(createContext.Length);

                            byte[] nextValue = BitConverter.GetBytes(alignedLen);
                            Array.Copy(nextValue, createContext, nextValue.Length);

                            ms.Write(createContext, 0, createContext.Length);

                            //write the padding 0;
                            for (int j = 0; j < (alignedLen - createContext.Length); j++)
                            {
                                ms.WriteByte(0);
                            }
                        }
                        else
                        {
                            ms.Write(createContext, 0, createContext.Length);
                        }
                    }

                    packet.PayLoad.Buffer = ms.ToArray();
                    packet.PayLoad.CreateContextsLength = (uint)packet.PayLoad.Buffer.Length;
                }
            }

            packet.Sign();

            return packet;
        }
        /// <summary>
        /// modify the header of packet because it is a async packet
        /// </summary>
        /// <param name="packet">The packet</param>
        /// <param name="endpoint">The endpoint of client</param>
        /// <param name="asyncId">The asyncId</param>
        private void ModifyAsyncHeader(Smb2SinglePacket packet, Smb2Endpoint endpoint, ulong asyncId)
        {
            packet.Header.Flags |= Packet_Header_Flags_Values.FLAGS_ASYNC_COMMAND;

            packet.Header.ProcessId = (uint)asyncId;
            packet.Header.TreeId = (uint)(asyncId >> 32);

            //for finnal async response, if Interim Response has been send, it does not grand
            //any credits because credits has been granded in Interim Response
            if (context.connectionList[endpoint.EndpointId].asyncCommandList.ContainsKey(asyncId))
            {
                packet.Header.CreditRequest_47_Response = 0;
            }
            else
            {
                //grand credits as normal
            }
        }
        public Smb2ErrorResponsePacket CreateErrorResponse(
            Smb2Endpoint endpoint,
            uint status,
            ulong messageId,
            byte[] errorData
            )
        {
            Smb2ErrorResponsePacket packet = new Smb2ErrorResponsePacket();

            SetHeader(packet, status, endpoint, messageId);

            packet.PayLoad.StructureSize = ERROR_Response_packet_StructureSize_Values.V1;
            packet.PayLoad.Reserved = ERROR_Response_packet_Reserved_Values.V1;

            if (errorData == null)
            {
                packet.PayLoad.ByteCount = 0;
                //If the ByteCount field is zero then the server MUST supply an ErrorData
                //field that is one byte in length
                packet.PayLoad.ErrorData = new byte[1];
            }
            else
            {
                packet.PayLoad.ErrorData = errorData;
                packet.PayLoad.ByteCount = (uint)errorData.Length;
            }

            packet.Header.Flags = packet.Header.Flags & ~Packet_Header_Flags_Values.FLAGS_SIGNED;

            packet.Sign();

            return packet;
        }
 /// <summary>
 /// Set packet header field
 /// </summary>
 /// <param name="packet">The packet</param>
 /// <param name="endpoint">The client endpoint</param>
 /// <param name="messageId">The messageId of request packet</param>
 private void SetHeader(Smb2SinglePacket packet, Smb2Endpoint endpoint, ulong messageId)
 {
     SetHeader(packet, 0, endpoint, messageId);
 }
        public Smb2IOCtlResponsePacket CreateIOCtlResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            byte[] input,
            byte[] output
            )
        {
            Smb2IOCtlResponsePacket packet = new Smb2IOCtlResponsePacket();

            Smb2IOCtlRequestPacket requestPacket = context.FindRequestPacket(endpoint.EndpointId, messageId)
                as Smb2IOCtlRequestPacket;

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.CtlCode = (uint)requestPacket.PayLoad.CtlCode;
            packet.PayLoad.FileId = requestPacket.PayLoad.FileId;
            packet.PayLoad.Flags = IOCTL_Response_Flags_Values.V1;

            int bufferLen = 0;

            if (input != null)
            {
                packet.PayLoad.InputCount = (uint)input.Length;
                packet.PayLoad.InputOffset = Smb2Consts.InputOffsetInIOCtlResponse;
                bufferLen += Smb2Utility.AlignBy8Bytes(input.Length);
            }

            if (output != null)
            {
                packet.PayLoad.OutputCount = (uint)output.Length;
                packet.PayLoad.OutputOffset = (uint)(Smb2Consts.InputOffsetInIOCtlResponse + bufferLen);
                bufferLen += output.Length;
            }

            byte[] buffer = new byte[bufferLen];

            if (input != null)
            {
                Array.Copy(input, buffer, input.Length);
            }

            if (output != null)
            {
                Array.Copy(output, 0, buffer, packet.PayLoad.OutputOffset - Smb2Consts.InputOffsetInIOCtlResponse,
                    output.Length);
            }

            packet.PayLoad.Reserved = IOCTL_Response_Reserved_Values.V1;
            packet.PayLoad.Reserved2 = IOCTL_Response_Reserved2_Values.V1;
            packet.PayLoad.StructureSize = IOCTL_Response_StructureSize_Values.V1;
            packet.PayLoad.Buffer = buffer;

            packet.Sign();

            return packet;
        }
        private void SetHeader(Smb2SinglePacket packet, uint status, Smb2Endpoint endpoint, ulong messageId)
        {
            packet.Endpoint = endpoint;

            Smb2SinglePacket singleRequestPacket = context.FindRequestPacket(endpoint.EndpointId, messageId)
                as Smb2SinglePacket;

            bool isRequestSigned = false;
            ushort clientRequestCredits = 0;

            if (singleRequestPacket == null)
            {
                packet.Header.MessageId = 0;
                packet.Header.Command = Smb2Command.NEGOTIATE;
            }
            else
            {
                packet.Header.MessageId = singleRequestPacket.Header.MessageId;
                packet.Header.SessionId = singleRequestPacket.Header.SessionId;
                packet.Header.TreeId = singleRequestPacket.Header.TreeId;
                packet.Header.ProcessId = singleRequestPacket.Header.ProcessId;
                packet.Header.Command = singleRequestPacket.Header.Command;

                if (((singleRequestPacket).Header.Flags & Packet_Header_Flags_Values.FLAGS_SIGNED)
                    == Packet_Header_Flags_Values.FLAGS_SIGNED)
                {
                    isRequestSigned = true;
                }

                clientRequestCredits = singleRequestPacket.Header.CreditRequest_47_Response;
            }

            packet.Header.CreditRequest_47_Response = Smb2Utility.CaculateResponseCredits(clientRequestCredits,
                context.connectionList[endpoint.EndpointId].commandSequenceWindow.Count);

            packet.Header.ProtocolId = Smb2Consts.Smb2ProtocolId;
            packet.Header.Signature = new byte[Smb2Consts.SignatureSize];
            packet.Header.StructureSize = Packet_Header_StructureSize_Values.V1;
            packet.Header.Status = status;

            packet.Header.Flags |= Packet_Header_Flags_Values.FLAGS_SERVER_TO_REDIR;

            if (packet.Header.SessionId != 0 &&
                (isRequestSigned || context.ShouldPacketBeSigned(singleRequestPacket.GetSessionId())))
            {
                packet.Header.Flags |= Packet_Header_Flags_Values.FLAGS_SIGNED;

                (packet as Smb2SinglePacket).SessionKey = context.globalSessionTable[singleRequestPacket.GetSessionId()].sessionKey;
            }
        }
        public Smb2LeaseBreakNotificationPacket CreateLeaseBreakNotificationResponse(
            Smb2Endpoint endpoint,
            LEASE_BREAK_Notification_Packet_Flags_Values flags,
            byte[] leaseKey,
            LeaseStateValues currentLeaseState,
            LeaseStateValues newLeaseState
            )
        {
            Smb2LeaseBreakNotificationPacket packet = new Smb2LeaseBreakNotificationPacket();

            packet.Header.Flags = Packet_Header_Flags_Values.FLAGS_SERVER_TO_REDIR;
            packet.Header.Command = Smb2Command.OPLOCK_BREAK;
            packet.Header.MessageId = ulong.MaxValue;
            packet.Header.ProtocolId = Smb2Consts.Smb2ProtocolId;
            packet.Header.Signature = new byte[Smb2Consts.SignatureSize];
            packet.Header.StructureSize = Packet_Header_StructureSize_Values.V1;

            packet.Endpoint = endpoint;

            packet.PayLoad.AccessMaskHint = LEASE_BREAK_Notification_Packet_AccessMaskHint_Values.V1;
            packet.PayLoad.BreakReason = LEASE_BREAK_Notification_Packet_BreakReason_Values.V1;
            packet.PayLoad.CurrentLeaseState = currentLeaseState;
            packet.PayLoad.Flags = LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED;
            packet.PayLoad.LeaseKey = leaseKey;
            packet.PayLoad.NewLeaseState = newLeaseState;
            packet.PayLoad.Reserved = LEASE_BREAK_Notification_Packet_Reserved_Values.V1;
            packet.PayLoad.ShareMaskHint = LEASE_BREAK_Notification_Packet_ShareMaskHint_Values.V1;
            packet.PayLoad.StructureSize = LEASE_BREAK_Notification_Packet_StructureSize_Values.V1;

            packet.Sign();

            return packet;
        }
        public Smb2ChangeNotifyResponsePacket CreateChangeNotifyResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            uint status,
            ulong messageId,
            params FILE_NOTIFY_INFORMATION[] notifyInfo
            )
        {
            Smb2ChangeNotifyResponsePacket packet = CreateChangeNotifyResponse(endpoint, status, messageId, notifyInfo);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        public Smb2LockResponsePacket CreateLockResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            ulong messageId
            )
        {
            Smb2LockResponsePacket packet = CreateLockResponse(endpoint, messageId);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        public Smb2CloseResponsePacket CreateCloseResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            CLOSE_Response_Flags_Values flags,
            _FILETIME creationTime,
            _FILETIME lastAccessTime,
            _FILETIME lastWriteTime,
            _FILETIME changeTime,
            ulong allocationSize,
            ulong endofFile,
            File_Attributes fileAttributes
            )
        {
            Smb2CloseResponsePacket packet = new Smb2CloseResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.AllocationSize = allocationSize;
            packet.PayLoad.ChangeTime = changeTime;
            packet.PayLoad.CreationTime = creationTime;
            packet.PayLoad.EndofFile = endofFile;
            packet.PayLoad.FileAttributes = fileAttributes;

            if (fileAttributes == File_Attributes.NONE)
            {
                packet.PayLoad.Flags = CLOSE_Response_Flags_Values.NONE;
            }
            else
            {
                packet.PayLoad.Flags = CLOSE_Response_Flags_Values.V1;
            }

            packet.PayLoad.LastAccessTime = lastAccessTime;
            packet.PayLoad.LastWriteTime = lastWriteTime;
            packet.PayLoad.Reserved = CLOSE_Response_Reserved_Values.V1;
            packet.PayLoad.StructureSize = CLOSE_Response_StructureSize_Values.V1;

            packet.Sign();

            return packet;
        }
        public Smb2NegotiateResponsePacket CreateNegotiateResponse(
            Smb2Endpoint endpoint,
            DialectRevision_Values dialectRevision,
            SecurityPackage securityPackage,
            ServerContextAttribute contextAttribute
            )
        {
            Smb2NegotiateResponsePacket packet = new Smb2NegotiateResponsePacket();

            SetHeader(packet, endpoint, 0);

            packet.PayLoad.SecurityMode |= NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;

            if (context.requireMessageSigning)
            {
                packet.PayLoad.SecurityMode |= NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED;
            }

            packet.PayLoad.StructureSize = NEGOTIATE_Response_StructureSize_Values.V1;
            packet.PayLoad.DialectRevision = dialectRevision;
            packet.PayLoad.ServerGuid = context.serverGuid;

            if (context.isDfsCapable)
            {
                packet.PayLoad.Capabilities |= NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DFS;
            }

            packet.PayLoad.MaxTransactSize = uint.MaxValue;
            packet.PayLoad.MaxWriteSize = uint.MaxValue;
            packet.PayLoad.MaxReadSize = uint.MaxValue;

            packet.PayLoad.SystemTime = Smb2Utility.DateTimeToFileTime(DateTime.Now);
            packet.PayLoad.ServerStartTime = Smb2Utility.DateTimeToFileTime(context.serverStartTime);

            SecurityPackageType package = SecurityPackageType.Negotiate;

            if (securityPackage == SecurityPackage.Kerberos)
            {
                package = SecurityPackageType.Kerberos;
            }
            else if (securityPackage == SecurityPackage.Nlmp)
            {
                package = SecurityPackageType.Ntlm;
            }

            AccountCredential credential = new AccountCredential(null, null, null);

            context.connectionList[endpoint.EndpointId].credential = credential;
            context.connectionList[endpoint.EndpointId].packageType = package;
            context.connectionList[endpoint.EndpointId].contextAttribute = (ServerSecurityContextAttribute)contextAttribute;

            if (package == SecurityPackageType.Negotiate)
            {
                context.connectionList[endpoint.EndpointId].gss = new SspiServerSecurityContext(
                    package,
                    credential,
                    null,
                    context.connectionList[endpoint.EndpointId].contextAttribute,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

                //Generate the first token
                context.connectionList[endpoint.EndpointId].gss.Accept(null);

                packet.PayLoad.Buffer = context.connectionList[endpoint.EndpointId].gss.Token;
                packet.PayLoad.SecurityBufferOffset = Smb2Consts.SecurityBufferOffsetInNegotiateResponse;
            }
            else
            {
                packet.PayLoad.Buffer = new byte[0];
            }
            packet.PayLoad.SecurityBufferLength = (ushort)packet.PayLoad.Buffer.Length;

            packet.Sign();

            return packet;
        }
        public Smb2ChangeNotifyResponsePacket CreateChangeNotifyResponse(
            Smb2Endpoint endpoint,
            uint status,
            ulong messageId,
            params FILE_NOTIFY_INFORMATION[] notifyInfo
            )
        {
            Smb2ChangeNotifyResponsePacket packet = new Smb2ChangeNotifyResponsePacket();

            SetHeader(packet, status, endpoint, messageId);

            if (notifyInfo == null)
            {
                packet.PayLoad.Buffer = new byte[0];
            }
            else
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    foreach (FILE_NOTIFY_INFORMATION oneNotifyInfo in notifyInfo)
                    {
                        byte[] oneNotifyInfoArray = TypeMarshal.ToBytes(oneNotifyInfo);

                        ms.Write(oneNotifyInfoArray, 0, oneNotifyInfoArray.Length);
                    }

                    packet.PayLoad.Buffer = ms.ToArray();
                    packet.PayLoad.OutputBufferLength = (uint)packet.PayLoad.Buffer.Length;
                    packet.PayLoad.OutputBufferOffset = Smb2Consts.OutputBufferOffsetInChangeNotifyResponse;
                }
            }

            packet.Sign();

            return packet;
        }