private Smb2Packet DecodeSingleResponsePacket( byte[] messageBytes, bool ignoreCompoundFlag, ulong realSessionId, uint realTreeId, out int consumedLength, out int expectedLength ) { Packet_Header smb2Header; bool isLeaseBreakPacket = false; int offset = 0; smb2Header = TypeMarshal.ToStruct<Packet_Header>(messageBytes, ref offset); if (smb2Header.Command == Smb2Command.OPLOCK_BREAK) { ushort structureSize = TypeMarshal.ToStruct<ushort>(messageBytes, ref offset); if (structureSize == (ushort)OplockLeaseBreakStructureSize.LeaseBreakNotification || structureSize == (ushort)OplockLeaseBreakStructureSize.LeaseBreakResponse || structureSize == 9) // Add this condition temporally to handle LeaseBreakResponse is error response (i.e. structureSize == 9), but this will still hide the condition when OplockBreakResponse is error response { isLeaseBreakPacket = true; } } Smb2SinglePacket packet = null; ushort structSize = BitConverter.ToUInt16(messageBytes, Smb2Consts.Smb2HeaderLen); switch (smb2Header.Command) { case Smb2Command.CANCEL: packet = new Smb2CancelResponsePacket(); break; case Smb2Command.CHANGE_NOTIFY: packet = new Smb2ChangeNotifyResponsePacket(); break; case Smb2Command.CLOSE: packet = new Smb2CloseResponsePacket(); break; case Smb2Command.CREATE: packet = new Smb2CreateResponsePacket(); break; case Smb2Command.ECHO: packet = new Smb2EchoResponsePacket(); break; case Smb2Command.FLUSH: packet = new Smb2FlushResponsePacket(); break; case Smb2Command.IOCTL: packet = new Smb2IOCtlResponsePacket(); break; case Smb2Command.LOCK: packet = new Smb2LockResponsePacket(); break; case Smb2Command.LOGOFF: packet = new Smb2LogOffResponsePacket(); break; case Smb2Command.NEGOTIATE: packet = new Smb2NegotiateResponsePacket(); break; case Smb2Command.OPLOCK_BREAK: if (smb2Header.MessageId == ulong.MaxValue) { if (!isLeaseBreakPacket) { packet = new Smb2OpLockBreakNotificationPacket(); } else { packet = new Smb2LeaseBreakNotificationPacket(); } } else { if (!isLeaseBreakPacket) { packet = new Smb2OpLockBreakResponsePacket(); } else { packet = new Smb2LeaseBreakResponsePacket(); } } break; case Smb2Command.QUERY_DIRECTORY: packet = new Smb2QueryDirectoryResponePacket(); break; case Smb2Command.QUERY_INFO: packet = new Smb2QueryInfoResponsePacket(); break; case Smb2Command.READ: packet = new Smb2ReadResponsePacket(); break; case Smb2Command.SESSION_SETUP: packet = new Smb2SessionSetupResponsePacket(); break; case Smb2Command.SET_INFO: packet = new Smb2SetInfoResponsePacket(); break; case Smb2Command.TREE_CONNECT: packet = new Smb2TreeConnectResponsePacket(); break; case Smb2Command.TREE_DISCONNECT: packet = new Smb2TreeDisconnectResponsePacket(); break; case Smb2Command.WRITE: packet = new Smb2WriteResponsePacket(); break; default: throw new InvalidOperationException("Received an unknown packet! the type of the packet is " + smb2Header.Command.ToString()); } if (IsErrorPacket(smb2Header)) { var error = new Smb2ErrorResponsePacket(); error.FromBytes(messageBytes, out consumedLength, out expectedLength); packet.Header = error.Header; packet.Error = error; } else { packet.FromBytes(messageBytes, out consumedLength, out expectedLength); } //if ignoreCompoundFlag is false, means the process of decoding this packet //is not part of the process of decoding a compound packet. We will update //context here. if (!ignoreCompoundFlag) { // TODO } 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; }